How to match a value of a list of numbers to item from a list of names in netlogo? - netlogo

I am trying something (in netlogo), but it is not working. I want a value of a position from a list of numbers. And I want to use the number that comes out of it to retrieve a name from a list of names.
So if I have a list like [1 2 3 4] en a list with ["chicken" "duck" "monkey" "dog"]
I want my number 2 to correspond with "duck".
So far, my zq is a list of numbers and my usedstrategies is a list of names.
let m precision (max zq) 1
let l position m zq
let p (position l zq) usedstrategies
But when I try this the result will be false, because l is not part of usedstrategies.
Ideas?

You need the item primitive to select from the list after matching on the other list. I am not sure what the precision line is for. However, here is a self contained piece of code that I think demonstrates what you want to do. Note that NetLogo counts positions from 0, not 1. I also used arbitrary numbers in the list so you don't get confused between the number in the list and its position.
to testme
let usedstrategies (list "chicken" "duck" "monkey" "dog")
let zq (list 5 6 7 8)
let strategynum position 7 zq
let thisstrategy item strategynum usedstrategies
type "Selected strategy number " type strategynum
type " which is " print thisstrategy
end

Jen's solution is perfectly fine, but I think this could also be a good use case for the table extension. Here is an example:
extensions [table]
to demo
let usedstrategies ["chicken" "duck" "monkey" "dog"]
let zq [5 6 7 8]
let strategies table:from-list (map list zq usedstrategies)
; get item corresponding with number 7:
print table:get strategies 7
end
A "table", here, is a data structure where a set of keys are associated with values. Here, your numbers are the keys and the strategies are the values.
If you try to get an item for which there is no key in the table (e.g., table:get strategies 9), you'll get the following error:
Extension exception: No value for 9 in table.
Here is a bit more detail about how the code works.
To construct the table, we use the table:from-list reporter, which takes a list of lists as input and gives you back a table where the first item of each sublist is used as a key and the second item is used as a value.
To construct our list of lists, we use the map primitive. This part is a bit more tricky to understand. The map primitive needs two kind of inputs: one or more lists, and a reporter to be applied to elements of these lists. The reporter comes first, and the whole expression needs to be inside parentheses:
(map list zq usedstrategies)
This expression "zips" our two lists together: it takes the first element of zq and the first element of usedstrategies, passes them to the list reporter, which constructs a list with these two elements, and adds that result to a new list. It then takes the second element of zq and the second element of usedstrategies and does the same thing with them, until we have a list that looks like:
[[5 "chicken"] [6 "duck"] [7 "monkey"] [8 "dog"]]
Note that the zipping expression could also have be written:
(map [ [a b] -> list a b ] zq usedstrategies)
...but it's a more roundabout way to do it. The list reporter by itself is already what we want; there is no need to construct a separate anonymous reporter that does the same thing.

Related

Multiple Knapsacks with Fungible Items

I am using cp_model to solve a problem very similar to the multiple-knapsack problem (https://developers.google.com/optimization/bin/multiple_knapsack). Just like in the example code, I use some boolean variables to encode membership:
# Variables
# x[i, j] = 1 if item i is packed in bin j.
x = {}
for i in data['items']:
for j in data['bins']:
x[(i, j)] = solver.IntVar(0, 1, 'x_%i_%i' % (i, j))
What is specific to my problem is that there are a large number of fungible items. There may be 5 items of type 1 and 10 items of type 2. Any item is exchangeable with items of the same type. Using the boolean variables to encode the problem implicitly assumes that the order of the assignment for the same type of items matter. But in fact, the order does not matter and only takes up unnecessary computation time.
I am wondering if there is any way to design the model so that it accurately expresses that we are allocating from fungible pools of items to save computation.
Instead of creating 5 Boolean variables for 5 items of type 'i' in bin 'b', just create an integer variable 'count' from 0 to 5 of items 'i' in bin 'b'. Then sum over b (count[i][b]) == #item b

Scala Apriori Algorithm : if first index value is same, then Generate Three item set from two items set list

i want this answer
if Input list is >> List( List("A","B"),List("A","C"),List("B","C"),List("B","D"))
Output should be >> List(List("A", "B","C"),List("B","C","D"))
i think it should be done as following>> all indices having first element same are grouped e.g if first element is "A" then group will be ("A","B","B","C").distinct = ("A","B","C")

Selecting random values in a set in mathematica

I have a set which has {0} and other 8 elements, total 9 elements. I want to choose random 3 value in this set and create a 3x1 column matrix. This will repeat all possible choices in the set. How can I do?
As #Picket said in comment,
The way RandomSample works will ensure it will not output the same choice twice in a single call
If your list is small, you can generate all subsets and sample it.
Example
RandomSample[Subsets[{a, b, c, d, e, f}, {3}], 7]
will generate all (20) subsets with 3 (distinct) elements and then pick 7 different uniformly (there are options to weight each member differently, chose the random generator, etc.).
RandomSample[Flatten[Permutations /# Subsets[{a, b, c, d, e, f}, {3}], 1], 13]
will generate all (120) possible ordered selections of 3 distinct elements among a set of 6 elements and give a sample of 13 distinct elements of this list.
If what you want is a random ordering of all possible subsets of size 3, or of all ordered selections without duplicate of size 3 just ask the same way but with the exact number of such sets.
myset = { foo, foo2, foo3, foo5 };
RandomSample[Subsets[myset, {3}], Binomial[Length[myset],3 ]]
RandomSample[Flatten[Permutations /# Subsets[myset, {3}], 1], 3!*Binomial[Length[myset],3 ] ]
(if you ask more than the exact number of possibilities, RandomSample will complain)
Now if your initial set is large so that the set of subsets is impractical for generation time and memory, take advantage of representing set composition by numbers, even if it is not perfect in term of uniform distribution. Say that your initial set has 20 distinct elements. A three digit number in base 20 can represent any selection of 3. If you account for the need to filter out the few with one digit appearing more than once
20^3/(3!*Binomial[20, 3]) // N
1.16959
You are probably safe by generating 25% more numbers than what you need and filtering the ones with repetition:
Cases[IntegerDigits[RandomSample[0 ;; 20^3-1, Ceiling[31*(1 + 1/4)] ], 20, 3], _?(Length[Union[#]] == 3 &), 1, 31]
This generates a random sample of 39 distinct 3-digit numbers in base 20 and select the first 31 with no duplicates in the form of a list of 3-coordinates vectors.

Is it possible to concatenate lists by including one list in another?

I have two lists that will be created during runtime. I want to combine the lists that have been made so that the data can be accessed later on within the code , with the end goal of simplifying my code and improving my model efficiency. Can lists be concatenated by the inclusion of one within the other or is there another way?
Thanks.
The usual way to concatenate lists is by using the sentence primitive. This will give you a new list made with the elements of your two original lists, like in Jen's answer.
Alternatively, you could use the list primitive to build a list with your two original lists included as sub-lists.
The following example shows both methods:
to setup
let list1 [ 1 2 3 ]
let list2 [ 4 5 6 ]
print sentence list1 list2 ; will print: [1 2 3 4 5 6]
print list list1 list2 ; will print: [[1 2 3] [4 5 6]]
end
Which one you should prefer depends, of course, on what you want to do with it...
The sentence command can combine two lists without brackets left
to setup
let mylist1 [1 2 3]
let mylist2 [4 5 6]
set mylist1 sentence mylist1 mylist2
show mylist1
end

How to do sum of list subset in kdb?

If you have a list and another list with indices (limited number) in of the first list in ascending order.
How can you get a sum of elements in the first list between consecutive indices in the second list.
e.g:
list1: til 100;
idx: (1 20 50 70 100);
How can we get a list with sum of elements of list from elements 1:20, 20:50, 50:70, 70:100?
The obvious approach would be to use # and _ on elements of the idx but can we do that iteratively somehow without using first, first 1_idx etc.
Something like this would work:
q)sum each idx cut list1
190 1035 1190 2535 0
cut operates by cutting the second argument at the indices given in the first. Hence why you see the 0 at the end of the result, as it's cutting at the 100th element.