I would like to multiply the values of two different agent breeds with a function
to-report prod-val-tables [ inter popular ]
let ans 0
foreach (table:keys inter) [ [?] ->
set ans (ans + (table:get inter ?) * (table:get popular ?)) ]
report ans
end
but when I call this function
prod-val-tables we-interest popularity
it gives me an error because we-interestand popularity are from different breeds.
How could I solve it? Thank you very much for your help.
Related
I am quite new to NetLogo and here is what I am stuck here for weeks.
What I want to do is to make agents to be in group of 4 for 2 teams.
My plan is to make a function hold 4 turtles id,
to assign-groupmates [a1 a2 a3 a4]
and assign them to team 1
assign-groupmates [a1 a2 a3 a4] =team1[]
if team1 > 4
assign-groupmates [a1 a2 a3 a4] =team2[]
What I done is:
to assign-groupmates [ f g h i]
let A who random f
let B who random g
let C who random h
let D who random i
ifelse f != g, g != h, h != i, i != g
[ set group-id 1
separate
align
cohere ]
[assign-groupmates [W X Y Z]
set group-id 2]
end
How can I find the turtles-id and how can i send them through parameter?
the turtles-id I used is who random.
Thank you.
There are many different ways to accomplish what you want, but let me start with a piece of general advice:
Don't use who numbers if you can avoid it.
They have some legitimate uses, but those are few and far between. They are error prone, they lead to ugly code, and they tend to make you think the wrong way about the problem you are trying to solve.
NetLogo lets you store direct references to agents, for example:
ask turtles [ set friend one-of other turtles ]
In general, use that instead.
In your case, though, you should probably not be storing individual references to agents. Since you are dealing with groups of agents, you should be working with agentsets instead.
Here is one suggestion: make a global list of agentsets called groups. In addition to that, have each agent store a reference to the agentset that constitute its group. Here is one way to accomplish that:
globals [ groups ]
turtles-own [ my-group ]
to setup
clear-all
let number-of-groups 2
let turtles-per-group 4
create-turtles turtles-per-group * number-of-groups
set groups [] ; empty list
repeat number-of-groups [
let new-group n-of turtles-per-group turtles with [
not is-agentset? my-group
]
ask new-group [ set my-group new-group ]
set groups lput new-group groups
]
print (word "First group: " sort first groups)
print (word "Second group: " sort last groups)
; each turtle can easily access other members of its group:
ask turtles [ show sort other my-group ]
end
This code has the advantage of being very flexible. If you ever want more than two groups, or more than four turtles per group, it's a very easy change.
Another piece of general advice: if you ever find yourself using multiple variables like a1, a2, a3, etc., you are probably doing something wrong. You should be using lists and/or agentsets instead.
Dear Netlogo community,
Last week I posted the question on the same forum about forming subset from a set in netlogo. Here is the link.
How to form subset form a set of numbers in Netlogo
The problem with the above thread is that it wont give the subsets if the set contains more than 21 elements. It throws java heap space out of memory exception. I believe this is because the above thread stored all subsets in one list and eventually list of list reached to its maximum range and throws java heap space out of memory exception. Any help in this regard will be valuable.
A set with N elements has 2^N subsets. Computationally, you cannot do anything with all of them once N is big, but you can still pick from them randomly. Let's assume your N elements are in a list. Then you can pick a random subset:
to-report random-subset [#lst]
let _result []
foreach #lst [
if (one-of [true false]) [
set _result lput ? _result
]
]
report _result
end
Note that this is equivalent to picking a random number in [0..(2^N-1)] and then selection the subset "corresponding" to that number.
If you prefer a more functional approach, you can use
to-report random-subset02 [#lst]
report filter (task [one-of [true false]]) #lst
end
Here is code that runs a task on every subset as soon as that subset is generated, without accumulating all of the subsets in memory:
to foreach-subset [xs fn]
foreach-subset-helper [] xs fn
end
to foreach-subset-helper [prefix xs fn]
ifelse empty? xs
[ (run fn prefix) ]
[ foreach-subset-helper prefix butfirst xs fn
foreach-subset-helper lput (first xs) prefix butfirst xs fn ]
end
Sample run:
observer> foreach-subset [1 2 3] task print
[]
[3]
[2]
[2 3]
[1]
[1 3]
[1 2]
[1 2 3]
Tasks in NetLogo are documented at http://ccl.northwestern.edu/netlogo/docs/programming.html#tasks.
In my code all turtles own n-features represented by a n-tuple (a1,a2,...,an). where each ai can take values 0 or 1.
I have created some links between turtles. If two turtles share k-features (coordinate-wise matching) and there is a link between them then we call the link as k-link.
How can I find for each k (between 0 to n) how many k-links are there in total?
You don't tell us much about how you have structured your code, so I'm going to assume that your n-tuples are implemented as lists (which would make the most sense in NetLogo).
Here is a full example:
turtles-own [ a ]
links-own [ k ]
globals [ n ]
to setup
ca
set n 5
crt 10 [ ; create turtles with random feature lists
set a n-values n [ random 2 ]
]
ask turtles [ ; make a full network
create-links-with other turtles
]
ask links [ ; calculate k for all links
set k k-of-feature-lists ([a] of end1) ([a] of end2)
]
foreach n-values (n + 1) [ ? ] [ ; display number of k-links
show (word ? "-links: " count links with [ k = ? ])
]
end
to-report k-of-feature-lists [ a1 a2 ]
report length filter [?] (map = a1 a2)
end
Apart from k-of-feature-lists, this is fairly trivial code. What k-of-feature-lists does is to:
transform two lists of features into a single list of booleans containing a true value if the corresponding element is equal in both feature lists and false if it is not. This is accomplished using map and the concise task syntax for =;
filter the list of booleans to keep only the true values;
report the length of that filtered list, which is equal to the number of features that where the same in a1 and a2;
There are plenty of other ways to do that (some more efficient) but this one is nice and concise.
I have a network where each link has a cost that is calculated as follows:
ask links [ set link-cost sum [node-cost] of both-ends ]
How can I calculate the total link cost (sum of link cost) between two nodes that are not neighbors ?
to total-link-node [ a b ] ;; where a and b are nodes
ask a [
print [link-cost] of (link-with b) ]
end
gives "OF expected input to be a link agentset or link but got NOBODY instead"
Thanks in advance for your help.
Here is a possible solution by using nw:path-to in the Extension NW as suggested by Seth (you can also used nw:weighted-path-to) :
to total-link-node [a b]
ask a [
show nw:path-to b
print sum (map [ [link-cost] of ? ] nw:path-to b) ]
end
I would like to report a count of the number of common features (e.g. [1 8 4] is three features) an agent (target_turtle) shares with each agent in an agentset (neighbor_turtle). Any suggestions please?
For example: If the agent has the features [1 8 7] and an agent from the agent set has the features [1 7 8], they share one common feature i.e. 1 . The features 8 and 7 are not included as the order of the features is relevant.
The current error I get is: All the list arguments to FOREACH must be the same length.
Cheers,
Marshall
;; reporting overlap between two agents
to-report overlap_between [target_turtle neighbor_turtle]
let suma 0
ask neighbor_turtle
[
(foreach [feature] of target_turtle [Feature] of neighbor_turtle
[ if ?1 = ?2 [ set suma suma + 1] ]
)
report suma
]
end
Your code seems almost correct already, though the ask neighbor_turtle part isn't necessary; you're already using of to switch perspectives.
The error message you're getting seems to indicate that you need to somehow handle the case where the turtle's feature lists aren't the same length.
I'll assume you just want to ignore any trailing items in the longer of the two lists. Here's code that does that:
to-report overlap-between [target-turtle neighbor-turtle]
let features1 [feature] of target-turtle
let features2 [feature] of neighbor-turtle
ifelse length features1 > length features2
[ set features1 sublist features1 0 length features2 ]
[ if length features2 > length features1
[ set features2 sublist features2 0 length features1 ] ]
report sum (map [ifelse-value (?1 = ?2) [1] [0]]
features1 features2)
end
Note that it's idiomatic in NetLogo to name variables like-this not like_this.