Counting the number of different links - netlogo

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.

Related

How to fix "Nothing named ? has been defined" error in NetLogo 6.0.4

I downloaded the modified random clusters code for generating neutral landscape models using the Millington's version of the modified random clusters approach in the NetLogo modeling commons. When I click the "generate-landscape" button, the "fill-landscape" procedure in the code causes a "Nothing named ? has been defined" error.
When I created the attached interface image and attempted to run the adjoining code below. The problem seems to be related to the question mark in the "occurrences" report function. The reduce function is not working as intended. Is there a work around for this? See interface, then code below:
ifelse ( any? neighbours with [ cluster != nobody ] ) ;; check if there are any assigned patches in neighbourhood
[
let covers []
ask neighbours with [ cluster != nobody ]
[
set covers fput cover covers ;;ask neighbours to add their covers to the list
]
let unique-covers remove-duplicates covers ;;create a list of unique covers
let max-cover-count -1 ;the number of neighbours with the maximum cover
let max-cover -1 ;the maximum cover
ifelse(length unique-covers > 1)
[
;if there is more than one unique-cover
foreach unique-covers ;for each of the unique covers
[
let occ occurrences ? covers ;count how many neighbours had this cover
ifelse(occ > max-cover-count) ;if the count is greater than the current maximum count
[
set max-cover ? ;set this as the dominant cover
set max-cover-count occ ;update the current maximum count
;---------------
to-report occurrences [x the-list]
report reduce
[ifelse-value (?2 = x) [?1 + 1] [?1]] (fput 0 the-list)
end
;---------------
The code is suppose to generate a neutral landscape model using the modified random clusters approach developed by Saura and Martinez-Millan (2000). However, the error "Nothing named ? has been defined" error the code from running smoothly. Looking forward to thoughts ...
The old ? syntax from NetLogo 5.x was replaced with the new -> syntax in NetLogo 6. See https://ccl.northwestern.edu/netlogo/docs/programming.html#anonymous-procedures
So, for example, in NetLogo 5, you would write:
foreach [0 1 2 3] [
print ?
]
in NetLogo 6, you write:
foreach [0 1 2 3] [ x ->
print x
]
A combination of Bryan's answer (first procedure) and the NetLogo Dictionary (second procedure) gives you the following. The comments indicate the new bits. Not tested.
ifelse ( any? neighbours with [ cluster != nobody ] )
[ let covers []
ask neighbours with [ cluster != nobody ]
[ set covers fput cover covers
]
let unique-covers remove-duplicates covers
let max-cover-count - 1 ; added a space around subtraction
let max-cover - 1 ; more spacing
ifelse(length unique-covers > 1)
[ foreach unique-covers
[ this-cover -> ; here's the new bit, calling ? 'this-cover'
let occ occurrences this-cover covers ; passes to the occurrences procedure
ifelse(occ > max-cover-count)
[ set max-cover this-cover ; using the name this-cover again
set max-cover-count occ
And for occurrences, you can take the procedure directly from the NetLogo Dictionary reduce example
to-report occurrences [#x #the-list]
report reduce
[ [occurrence-count next-item] -> ifelse-value (next-item = #x)
[occurrence-count + 1] [occurrence-count] ] (fput 0 #the-list)
end

How to make a list/array of turtles-on patch-here?

i have no experience on netlogo, so i am asking if someone know how to set the greatest energy of a turtle on patch-here. If i have on a patch an agent y and 3, 2 or 4 x´s , i want to agent y stay with the biggest energy of those 3,i know i have to do a loop but how do I loop not knowing how many x-type agents are in this patch?
breed [ y ys]
breed [ x ys]
x-own[ energy]
y-own [ energy ]
to move-y
ask y[
if count x-on patch-here > 2
[
set breed x
;anyone can help ?
let energy one-of x-on patch-here ; this is wrong because i dont want a random
]
]
end
hope you can help me =)
First of all, you probably should not be thinking in terms of loops. NetLogo has lots of primitives that operate on agentsets (like ask and of) and on lists (like foreach and map) but you almost never have to write an explicit loop with an index that you increment.
Another remark about your code: you have inverted the plural and the singular name when declaring your breeds. The plural has to come first, so it should be breed [ xs x ] instead of breed [ x xs ].
Now, regarding your specific problem: you don't need patch-here, since NetLogo also provides a <breeds>-here primitive that does what you need a bit more directly.
As for getting the maximum energy of all the xs on the path, you can simply use the max primitive:
breed [ xs x ]
breed [ ys y ]
xs-own [ energy]
ys-own [ energy ]
to move-y
ask ys [
if count xs-here > 2 [
set energy max [ energy ] of xs-here
set breed xs
]
]
end
Note that results might differ depending on whether you change to breed of the current y to xs before or after setting the energy. I'll let you try to figure out why.

Netlogo - Sum of lists of turtles

I would like to sum several lists of turtles. Lets call each variable turtle-list. There is only one list per variable, each list has the same number of items. If I have n turtles, I know that I can write
show (map + [turtle-list] of turtle 0 [turtle-list] of turtle 1 ... [turtle-
list] of turtle n)
Nevertheless, it may be very long and does not work if the number of turtles changes.
Is it possible to do it without writing the variable of each turtle ? Thank you for your help
I think you want to use reduce and sentence to convert a list of lists (from [turtle-list] of turtles) to a single list of values, then just sum that list:
turtles-own [ turtle-list ]
to setup
ca
crt 5 [
set turtle-list map [ i -> ( who + 1 ) * i ] [ 1 2 3 ]
]
reset-ticks
end
to sum-turtle-lists
show sum reduce sentence [turtle-list] of turtles
end
Let me know if that's not quite what you're after.
Edit:
Based on your comment, try this version:
to sum-turtle-lists
show reduce [ [ i a ] -> ( map + i a ) ] [turtle-list] of turtles
end

How to send parameters using NetLogo?

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.

How to calculate the total link cost between two nodes that are not neighbors?

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