let's say I have list
let mylist [0 1 2 3]
and I would like to generate random number from this array which is in every tick different than previous one.
Example: Tick one - generates 0
Tick two - generates 2
Tick three - generates 1
Tick four - generates 3
Now I have
let mylist [0 1 2 3]
let x one-of mylist
But that returns for example for two consecutive ticks number 0.
Any tips? Thank you.
One way is to store the number that was used in the last tick, compare it to the one chosen in the current tick, and choose a different one if they are the same.
globals [
previous_number
]
to generate
let current_number previous_number
let mylist [ 0 1 2 ]
while [ current_number = previous_number ] [
set current_number one-of mylist
]
set previous_number current_number
print current_number
end
Related
I'm wondering if it is possible to somehow "sort" items in an array to place them in "equal" spacings.
An example is more than hundreds of words so:
Apple - 1
Banana - 2
Pineapple - 3
Orange - 4
And this is an array:
[ 'Apple', 'Apple', 'Banana', 'Pineapple', 'Pineapple', 'Pineapple', 'Orange' ]
[ 1, 1, 2, 3, 3, 3, 4 ]
What I want to achieve is something similar to this:
[ 'Apple', 'Pineapple', 'Banana', 'Apple', 'Pineapple', 'Orange', 'Pineapple' ]
[ 1, 3, 2, 1, 3, 4, 3 ]
With this transformation Pineapple has 1 item offset between other 'Pineapple' and Apple is placed in [0] and [3] placement.
Before I start an implementation I'm looking for an already invented solution - it should be something related with standard deviation?
The class of algorithm you're looking for is called multiplexing. A multiplexer takes several input streams, and creates a single output stream, selecting one item at a time from the input. There are many different multiplexing strategies. I'll describe one that's easy to implement, and performs well.
The general idea is that each item has a name, rate, and accumulator, and the item with the largest value in its accumulator is chosen next. In the example given in the question, the rates are 2 for Apple, 1 for Banana, 3 for Pineapple, and 1 for Orange. The sum of the rates is the period, which is 7.
The algorithm operates as follows:
initialize all accumulators to 0
for each slot in one period:
choose the item with the largest accumulator, and add it to the output
update each accumulator by adding the rate to the accumulator
subtract the period from the accumulator of the chosen item
The table below shows how the algorithm progresses. The slots are labelled S1 thru S7. For each slot there are two columns of numbers, the accumulator value for each item, and the adjustment to the accumulator.
In slot 1, the Orange is chosen, so the adjustment to the accumulator is +1 -7 = -6 (add the rate, and subtract the period). For every other item the adjustment is equal to the rate. Notice that all the accumulators start at 0, and return to 0 after the seventh slot. Hence, the algorithm could be run for any number of slots, and it would simply repeat the same pattern.
Name Rate __S1__ __S2__ __S3__ __S4__ __S5__ __S6__ __S7__
Orange 1/7 0 -6 -6 +1 -5 +1 -4 +1 -3 +1 -2 +1 -1 +1 0
Banana 1/7 0 +1 1 +1 2 +1 3 -6 -3 +1 -2 +1 -1 +1 0
Apple 2/7 0 +2 2 +2 4 -5 -1 +2 1 +2 3 -5 -2 +2 0
Pineapple 3/7 0 +3 3 -4 -1 +3 2 +3 5 -4 1 +3 4 -4 0
Selected item: Orange Pine Apple Banana Pine Apple Pine
Here's an implementation in Python:
items = ['Apple', 'Apple', 'Banana', 'Pineapple', 'Pineapple', 'Pineapple', 'Orange']
# Convert the list of items into a list that contains the [name, rate, accumulator]
# for each item. The initial value for the accumulator is 0
counts = {}
for item in items:
counts[item] = counts.get(item, 0) + 1
rates = counts.items()
rates = [[name, rate, 0] for (name, rate) in rates]
rates.sort(key=lambda x:x[1])
# Run the multiplexer, which
# adds the item with the largest accumulator to the output
# updates all the accumulators by adding the rate to the accumulator
# subtracts the period from the chosen accumlator
output = []
period = len(items)
for i in range(period):
best = 0
for j in range(len(rates)):
if rates[j][2] > rates[best][2]: # compare accumulators
best = j
rates[j][2] += rates[j][1] # update accumulator
rates[best][2] -= period
output.append(rates[best][0]) # add an item to the output
print output # ['Orange', 'Pineapple', 'Apple', 'Banana', 'Pineapple', 'Apple', 'Pineapple']
Start off by ordering your words by number of occurences. Then iterate over them, first filling up all even indices, then all odd indices.
The first word can at most fill up all even indices. In most modern arrays there should always be at least as many slots with an even index as there are with an odd one. If your language doesn't qualify for that (i.e. one-based arrays), pick even or odd based on the number of available slots.
The second most common word can only occur at most as many times as the most common word, so there's no possibility this way that the same word winds up in two adjacent slots that way.
A simple python-implementation would look like this:
import math
def spaced_ordering(words):
words = sorted(words, key=words.count, reverse=True)
output = [None] * len(words)
for i in range(0, math.ceil(len(words) / 2)):
output[i * 2] = words[i]
for i in range(0, math.floor(len(words) / 2)):
output[i * 2 + 1] = words[math.ceil(len(words) / 2) + i]
return output
Note: The above implementation is neither exactly performant, nor exactly fancy, nor does it include checking for valid inputs (e.g. what happens if a word occurs more than math.ceil(len(words) / 2) times). It only serves to demonstrate the basic principle.
For the problem "Find the number of unique paths from source to destination in a 2d grid. You can move in 4 directions and only to positions with a 1 in them. You may not move to a position more than once."
For example in the below grid, the number of unique paths from top left to bottom right, moving in 4 directions is 4.
[ 1 1 1 1 ]
[ 1 1 0 1 ]
[ 0 1 0 1 ]
[ 1 1 1 1 ]
Solutions:
[ * * * * ] [ * * 1 1 ] [ * 1 1 1 ] [ * * * * ]
[ 1 1 0 * ] [ 1 * 0 1 ] [ * * 0 1 ] [ * * 0 * ]
[ 0 1 0 * ] [ 0 * 0 1 ] [ 0 * 0 1 ] [ 0 1 0 * ]
[ 1 1 1 * ] [ 1 * * * ] [ 1 * * * ] [ 1 1 1 * ]
Is this not a dynamic programming problem because we can't cache the number of ways from source to a point because there are exponential number of ways to reach that point?
Or is it possibly because to reach [x][y], we have to take number of sum of number of ways from [x][y-1], [x-1][y], [x+1][y], [x][y+1] but those directions would also have to take number of ways from [x][y], for example [x][y-1] would take ways from [x-1][y-1], [x][y], etc.
You cannot add a point to a path if the path already contains the point. So caching paths from {x, y} to the end doesn't help you count paths from some neighbour of {x, y}. For each neighbour, you need the number of paths not including that point, which will usually be a different number for each neighbour
How do you represent empty rows in CSR?
Suppose we have the following matrices:
* MATRIX 1 *
a 0 0
0 b 0
0 0 c
val = [ a b c ]
col = [ 0 1 2 ]
row = [ 0 1 2 ] <- makes sense!
—————————————————————
* MATRIX 2 *
a b c
0 0 0
0 0 0
val = [ a b c ]
col = [ 0 1 2 ]
row = [ 0 ] <— makes sense…? but how about…
—————————————————————
* MATRIX 3 *
0 0 0
a b c
0 0 0
val = [ a b c ]
col = [ 0 1 2 ]
row = [ 0 ] <— wait… how do we differentiate between MATRIX 2 and MATRIX 3?
MATRIX 1 is intuitive, but how do we represent the difference between MATRIX 2 and MATRIX 3? Do we use a negative integer for spacing?
Thanks
Take a look at The Wikipedia page. The IA vector (or as you call it "row"), is defined as:
The array IA is of length m + 1. It is defined by this recursive definition:
IA[0] = 0
IA[i] = IA[i − 1] + (number of nonzero elements on the (i − 1)-th row in the original matrix)
Thus, the first m elements of IA store the index into A of the first nonzero element in each row of M [ ed: but only for rows that have at least one such element, i.e. IA[i+1]>IA[i] ], and the last element IA[m] stores NNZ, the number of elements in A, which can be also thought of as the index in A of first element of a phantom row just beyond the end of the matrix M. The values of the i-th row of the original matrix is read from the elements A[IA[i]] to A[IA[i + 1] − 1] (inclusive on both ends), i.e. from the start of one row to the last index just before the start of the next.
Thus, in Matrix 1:
row = [0 1 2 3]
in Matrix 2:
row = [0 3 3 3]
in Matrix 3
row = [0 0 3 3]
The answer provided is close to being a great explanation but needs to be clarified a bit:
The first two bullet points give a clear prescription for the entries in IA.
But the next part,
"Thus, the first m elements of IA store the index into A of the first nonzero element in each row of M, and the last element IA[m] stores NNZ, the number of elements in A, which can be also thought of as the index in A of first element of a phantom row just beyond the end of the matrix M. The values of the i-th row of the original matrix is read from the elements A[IA[i]] to A[IA[i + 1] − 1]
(inclusive on both ends), i.e. from the start of one row to the last index just before the start of the next."
It is difficult to parse, because the references "IA", "m", "NNZ", "M", and "A" are not defined.
Is the length of "IA" equal to one plus the number of nonzero elements in the full matrix?. I think that "A" and "M" refer to the full matrix and the sparse matrix, but there isn't enough information to determine which is which. "NNZ" may refer to the number of nonzero elements in the full matrix. And "m" may be the same as "NNZ".
Would you mind completing the explanation by providing the definitions of "IA", "m", "NNZ", "M" and "A"?
Thanks in advance, it would be much appreciated!
I have a n x 1 matrix. I'm trying to find a way to "shift" all the elements position (loosing the last element) and then add an element in position 0,0 in this way:
From
[[ 10 ]
[ 5 ]
[ 2 ]
[ 3 ]
[ 1 ]
[ 5 ]]
to (adding a new element 2 in position 0,0)
[[ 2 ]
[ 10 ]
[ 5 ]
[ 2 ]
[ 3 ]
[ 1 ]]
I'm pretty close to the solution but I don't know how add elements to a nested list.
;initial matrix
set mymatrix matrix:from-column-list [[10 5 2 3 1 5]]
;temp
let list matrix:to-column-list mymatrix
let tmplist matrix:to-column-list states
; ERROR here: the result of fput is [2[10 5 2 3 1 5]]
set tmplist fput 2 tmplist
;new matrix
matrix:set-column mymatrix 0 tmplist
EDIT: I realized that indeed for my needs a matrix is an overkill. I solved switching to pure netlogo lists and doing my business in map-reduce.
If you just need elementwise multiplication of objects that are fundamentally one-dimensional, just use map.
Example: (map * [1 2] [3 4]) reports [3 8].
Now you can just do your bookkeeping with lists, which is much easier.
Even if (for some reason you have not stated) you really need matrix operations elsewhere, you almost surely should use lists for the bookkeeping you describe and then convert when necessary.
I have an image 640x480 img, and I want to replace pixels having values not in this list or array x=[1, 2, 3, 4, 5] with a certain value 10, so that any pixel in img which doesn't have the any of the values in x will be replaced with 10. I already know how to replace only one value using img(img~=1)=10 or multiple values using this img(img~=1 & img~=2 & img~=3 & img~=4 & img~=5)=10 but I when I tried this img(img~=x)=10 it gave an error saying Matrix dimensions must agree. So if anyone could please advise.
You can achieve this very easily with a combination of permute and bsxfun. We can create a 3D column vector that consists of the elements of [1,2,3,4,5], then use bsxfun with the not equals method (#ne) on your image (assuming grayscale) so that we thus create a 3D matrix of 5 slices. Each slice would tell you whether the locations in the image do not match an element in x. The first slice would give you the locations that don't match x = 1, the second slice would give you the locations that don't match x = 2, and so on.
Once you finish this, we can use an all call operating on the third dimension to consolidate the pixel locations that are not equal to all of 1, 2, 3, 4 or 5. The last step would be to take this logical map, which that tells you the locations that are none of 1, 2, 3, 4, or 5 and we'd set those locations to 10.
One thing we need to consider is that the image type and the vector x must be the same type. We can ensure this by casting the vector to be the same class as img.
As such, do something like this:
x = permute([1 2 3 4 5], [3 1 2]);
vals = bsxfun(#ne, img, cast(x, class(img)));
ind = all(vals, 3);
img(ind) = 10;
The advantage of the above method is that the list you want to use to check for the elements can be whatever you want. It prevents having messy logical indexing syntax, like img(img ~= 1 & img ~= 2 & ....). All you have to do is change the input list at the beginning line of the code, and bsxfun, permute and any should do the work for you.
Here's an example 5 x 5 image:
>> rng(123123);
>> img = randi(7, 5, 5)
img =
3 4 3 6 5
7 2 6 5 1
3 1 6 1 7
6 4 4 3 3
6 2 4 1 3
By using the code above, the output we get is:
img =
3 4 3 10 5
10 2 10 5 1
3 1 10 1 10
10 4 4 3 3
10 2 4 1 3
You can most certainly see that those elements that are neither 1, 2, 3, 4 or 5 get set to 10.
Aside
If you don't like the permute and bsxfun approach, one way would be to have a for loop and with an initially all true array, keep logical ANDing the final result with a logical map that consists of those locations which are not equal to each value in x. In the end, we will have a logical map where true are those locations that are neither equal to 1, 2, 3, 4 or 5.
Therefore, do something like this:
ind = true(size(img));
for idx = 1 : 5
ind = ind & img ~= idx;
end
img(ind) = 10;
If you do this instead, you'll see that we get the same answer.
Approach #1
You can use ismember,
which according to its official documentation for a case of ismember(A,B) would output a logical array of the same size as A and with 1's where
any element from B is present in A, 0's otherwise. Since, you are looking to detect "not in the list or array", you need to invert it afterwards, i.e. ~ismember().
In your case, you have img as A and x as B, so ~ismember(img,x) would give you those places where img~=any element in x
You can then map into img to set all those in it to 10 with this final solution -
img(~ismember(img,x)) = 10
Approach #2
Similar to rayryeng's solution, you can use bsxfun, but keep it in 2D which could be more efficient as it would also avoid permute. The implementation would look something like this -
img(reshape(all(bsxfun(#ne,img(:),x(:).'),2),size(img))) = 10