Incrementing in a list efficiently - arrays

I have a list:
foo = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Currently, I increment a known number of consecutive indices by a given value:
def increment(index, length, some_value, a_list):
for i in range(index, index+length):
a_list[i] += some_value
return a_list
foo = increment(2,3,4,foo)
# [0, 0, 4, 4, 4, 0, 0, 0, 0, 0]
However, the problem is that I would be doing this over a range of 50-100 "length" and would be doing this millions of times. So, my looping would pose a considerable problem to computational time (I believe). Is there a way to add a given value to all indices within a given range without having to loop through the given indices?

Simon Tatham wrote something about "Cumulative Frequency Tables": http://www.chiark.greenend.org.uk/~sgtatham/algorithms/cumulative.html
This would apparently get you log times:
def increment(index, length, some_value, a_frequency_table):
// increment "frequency" of (index) by some_value
// decrement "frequency" of (index+length-1) by some_value
He also links C-code on the bottom of the page. If I understood your question right, it should be possible to adopt.

Given your requirements, it looks to me as though you doing this correctly in regards to performance. The only thing I can see to improve performance is very miniscule... I wouldn't bother returning the array, as it is unnecessary. Beyond that, everything looks sound.
def increment(index, length, some_value, a_list):
for i in range(index, index+length):
a_list[i] += some_value
increment(2,3,4,foo)
# [0, 0, 4, 4, 4, 0, 0, 0, 0, 0]

Related

Returning Index of Array with Maximum Element Value

I have the following np.array
arry=[0, 0, np.array([858.56]), 0, 0, 0, 0, np.array([59.778]), np.array([817.752])]
I am using the following code to find the index where the array element is maximum:
maximum=np.where(arry == np.amax(arry))
However, I am getting wrong index. What could be the problem?

Count most frequent element in an array in Minizinc

It's a very simple thing that I want to do in Minizinc. I have an array of integer values, and I want to know the number of times that the most common value in it occurs. I can't figure out how to do that. I hope someone can help.
I don't know if this is the most effective method, but it works, basically for each element in the array you sum the number of times that value appears in the array and store that in an auxliar array, and then take the find the maximum value that appears in the auxliar array, so in the example 14 appears 3 times so repeats holds 3 for every element corresponding to the 14.
At the end I added the one liner version of everything above, where instead of storing the array of repeats you generate it in place, its the line of max_repeats.
% count the number of times that the most common value is repeated in an array
% As an example lets make a 7 element array
% size
int : n = 7;
% index set
set of int : SET = 1..n;
% the values
array [SET] of int : x = [15,14,39,23,14,14,8];
% auxiliar variable to carry the count
array [SET] of var int : repeats;
% we will count the number of times that value repeats
constraint forall(i in SET)(repeats[i] = sum(j in SET)(x[i] = x[j]) );
% the value of the most repeated element in the array
var int : value;
% if the number of repeats of that element is the maximum
% then value is equal to that element
constraint forall(i in SET)(repeats[i] = max(repeats) -> value = x[i]);
% this does the same but in one line
var int : max_repeats = max([sum(j in SET)(x[i] = x[j]) | i in SET]);
solve satisfy;
output ["Original values " ++ show(x) ++ "\n"] ++
["Number of repeats of each element " ++ show(repeats) ++ "\n"] ++
["Maximum number of repeats : " ++ show(max(repeats))];
Original values [15, 14, 39, 23, 14, 14, 8]
Number of repeats of each element [1, 3, 1, 1, 3, 3, 1]
Maximum number of repeats : 3
The "classical" way of solving this problem is to use the global constriant global_cardinality together with max.
Below is one way to model this problem using these constraint; and it also shows the number that is the most frequent.
The drawback of using this approach is that one have to create a new array gcc (for "global cardinality count") which includes the number of occurrences for each number 0..upb (where upb is the upper bound of the array a), and that might be quite large if there are large numbers in the array. Also, one have to be a little careful about the indices, e.g. not forget to include 0 in gcc.
The advantage of this approach - apart from that is might be implemented efficient in a solver - is that one can add some extra constraints on the gcc array: here I added the the feature to show the number that is most frequent (using arg_max(a)); it might be more than one such numbers and will then give multiple solutions.
include "globals.mzn";
int: n = 7;
array[1..n] of int: a = [15, 14, 39, 23, 14, 14, 8];
% array[1..n] of var 0..29: a; % using decision variables
% upper value of a
int: upb = ub_array(a);
% Number of occurrences in a
array[0..upb] of var 0..n: gcc;
% max number of occurrenes
var 0..upb: z = max(gcc);
% The value of the max number of occurrences
var 0..upb: max_val = arg_max(gcc)-1;
solve satisfy;
constraint
% count the number of occurrences in a
global_cardinality(a, array1d(0..upb,[i | i in 0..upb]), gcc)
;
output [
"a: \(a)\n",
"upb: \(upb)\n",
"gcc: \(gcc)\n",
"z: \(z)\n",
"max_val: \(max_val)\n",
"ub_array(a): \(lb_array(a))..\(ub_array(a))\n",
];
Here is the output of this model:
a: [15, 14, 39, 23, 14, 14, 8]
upb: 39
gcc: [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
z: 3
max_val: 14
ub_array(a): 8..39
----------
==========

How to modify multiple elements at a time in C?

Say I got an array
unsigned char digit[] = {0, 1, 2, 3, 4, 5, 6, 7};
Yet I want to modify part of the array, make the array become something like:
{0, 1, 2, 3, 0, 0, 0, 0}
Enumerate every element I want to modify and alter them might take some effort. Especially when there's a large amount of elements I want to change. I know in some languages like Python I may do something using a single line of code:
a = np.array([0, 1, 2, 3, 4, 5, 6, 7])
a[4:] = [0, 0, 0, 0]
//a: array([0, 1, 2, 3, 0, 0, 0, 0])
So I wonder, is there a similar way to do that in C?
There are fewer possibilities in C, but in case of an unsigned char and setting its values to zero you could use memset:
memset(&digit[4], 0, 4);
Demo.
One options is that you could write a subroutine that would implement the interface that other languages provide "under the cover". You'll probably want to educate yourself on 'VARARGS' to make it take a variable number of arguments.
Others have already mentioned setting the array elements to a single value using memset, as a part of your follow up question you asked if some elements can be set to certain values like {1, 2, 3, 4}.
You can use memcpy here to achieve that. Since your type here is unsigned char I will keep that, but in general this method can be used for any type.
memcpy(&digit[4], ((unsigned char[4]){1, 2, 3, 4}), 4 * sizeof(unsigned char));
You can see the demo here.
I think that maybe not the shortest but something you can easy do is just:
digit[] = {0, 1, 2, 3, 4, 5, 6, 7}; %Having this
a=the number in your vector you want to start making ceros;
n=the lenght of digit;
for(i=a;i=n;i++)
{
digit[n]=0;
}
Is just a way I think you could use.
If you want to change an specific one just
b=position;
digit[b]=c; %Where c is the number you want to put in there.
I hope it works for you, good luck.

Haxe - How to initialize all members of an array to the same value?

I need to initialize an array with given size and same value.
For example, create an array of int that has size 10 and set all values to 0.
Int[] array = new Int[10]{0}
In other languages it's very easy, but I'm not sure how to solve this problem on Haxe.
Please help me.
You could use Array Comprehension
var array:Array<Int> = [for (i in 0...10) 0];
I would not use the word 'array' since Array is reserved and it's confusing, often I use 'arr' instead. No need to type it, that is inferred so it's bit cleaner and lighter:
var arr = [for (i in 0...10) 0];
A macro approach would put the result in the compiled code which would run faster.
var arr = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
and is explained here:
https://code.haxe.org/category/macros/build-arrays.html

Finding a subset which satisfies a certain condition

I have several arrays of numbers (each element of the array can only take a value of 0 or 1) like this
v1: 1; 0; 0; 1; 1;
v2: 0; 1; 0; 0; 1;
v3: 1; 1; 0; 1; 0;
v4: 1; 0; 0; 1; 0;
v5: 1; 1; 0; 1; 1;
v6: 1; 1; 0; 1; 1;
I wish to find subsets such that, when the arrays are summed, the resulting array has individual elements which are multiples of 2. For example, v1+v2+v3 gives a resulting array of 2, 2, 0, 2, 2. The resulting array can have any value that is a multiple of 2.
Another example:
v1: 1, 1, 1, 0, 1, 0
v2: 0, 0, 1, 0, 0, 0
v3: 1, 0, 0, 0, 0, 0
v4: 0, 0, 0, 1, 0, 0
v5: 1, 1, 0, 0, 1, 0
v6: 0, 0, 1, 1, 0, 0
v7: 1, 0, 1, 1, 0, 0
In this example, v1+v2+v5 and v3+v6+v7 are suitable answers.
I have a brute force solution in mind, but I wanted to check if there is a more efficient method. Is this equivalent to the subset sum problem?
Do you want to find all solutions or one?
This can find one solution (and I think it may be possible to extend it to find all solutions).
Represent each array as a binary number.
So v1 becomes 10011, v2 becomes 01001 etc.
Let * denote bitwise mod 2 addition.
e.g.
v1*v2*v3 = 00000
So our objective is to find arrays whose mod 2 addition is all zeroes.
Let u and v be any binary number.
Then u*v = 0 iff u = v.
e.g.
(v1*v2)*v3 = 0
v1*v2 = 11010 = v3.
Also if u*v = w then
u*v*v = w*v, so
u*0 = w*v,
u = w*v
So we can do a reverse search starting from 0. Suppose the final set of arrays contains v. Then v*T = 0, where T is some binary number. We have T = 0*v. If T is one of the given arrays then we are done. Otherwise we continue the search starting from T.
This is formally described below.
Each state is a binary number.
Let 0 be the initial state.
The given arrays are some subset of the state space, say S.
Our goal state is any element in S.
Let T be the required subset of arrays whose sum is 0.
At each state let the possible actions be * with any state not in T.
After each action put the array used in T.
If S = T at any non goal stage, then there is no solution.
Now we can run a DFS on this space to find a solution.

Resources