Netlogo sort variables - netlogo

I want to order these numbers in variables.
I tested with Ifs and didn't found the way of how to do it.
Then I tested with sort but it seems that i doesn't accept variables.
let ginyo00 [xcor] of coche 0
let ginyo01 [xcor] of coche 1
let ginyo02 [xcor] of coche 2
let ginyo03 [xcor] of coche 3
output-print ginyo00
output-print ginyo01
output-print ginyo02
output-print ginyo03
output-print "====="
set maxv max (list ginyo00 ginyo01 ginyo02 ginyo03)
show sort [ginyo00 ginyo01 ginyo02 ginyo03]
I need a way of sorting this values and knowing which are.

The sort primitive works on lists or agent sets, per the docs.
So you can use it with variables the same way you got the max, by using the list primitive to turn your variables into a list for sort:
show sort (list ginyo00 ginyo01 ginyo02 ginyo03)
You can also get this info without the intermediate variables:
let my-coches coches with [ who < 4 ]
ask my-coches [ output-print xcor ]
set maxv max ([ xcor ] of my-coches)
show sort ([ xcor ] of my-coches)
If what you actually want is the coches in sorted order instead of the values in order, you can use sort-on instead:
let sorted-coches sort-on [xcor] my-coches
show sorted-coches

Related

Netlogo: Making a turtle interact with anotherone after evaluating similarity in a given variable

I have several turtles each with three variables opinion1, opinion2 and opinion3. I need them to:
identify which of these three variables has the highest value
find another turtle in their network with a value at least as high
as the one found in 1.
update its own value found in 1. with
respect to that of the turtle found in 2.
What I have done doesn't really work because it only updates looking at o1 without really having a look at which of the tree (opinion1, opinion2 or opinion3) is the highest and THEN looking for a neighbour.
to update-opinion
ask turtles [
let my-nearby-turtles nw:turtles-in-radius 1
let my-opinion1 opinion1
set neighbour one-of my-nearby-turtles with [ opinion1 > my-opinion1 ]
if neighbour != nobody [
let opinion_n [opinion1] of neighbour
set opinion1 ((opinion1 + opinion_n) / (2))
]
]
end
I don't know a simple way to do this with unique variables like opinion1 etc, but maybe having a list of opinions instead of individual variables for each opinion will work. For example, with this setup:
extensions [ nw ]
turtles-own [
opinions
]
to setup
ca
resize-world -5 5 -5 5
set-patch-size 30
crt 30 [
set shape "dot"
set opinions n-values 3 [ precision random-float 10 2]
set color scale-color blue sum opinions -5 35
while [ any? other turtles-here ] [
move-to one-of neighbors4
]
]
ask turtles [
create-links-with turtles-on neighbors4
]
reset-ticks
end
You get something like this:
Where each turtle has an opinions list variable that is three items long. Now, you can have each turtle determine its highest opinion value using max, get that maximum values index position in the list using position, and then query that turtle's neighbors to see if any of them have a higher value in the same index position. If they do, modify your asking turtles opinions list using replace-item to be the average of the two values:
to go
ask turtles [
; Get adjacent turtles
let my-nearby-turtles nw:turtles-in-radius 1
; Identify the highest highest value variable of
; the current turtle, and get its list position
let my-opinion max opinions
let my-op-ind position my-opinion opinions
; Pick one of the turtles whose value in the same indexed
; position is higher than my-opinion
let influence one-of my-nearby-turtles with [
item my-op-ind opinions > my-opinion
]
; If that turtle exists, update my own opinions list as appropriate
if influence != nobody [
let new-opinion precision (
( [ item my-op-ind opinions ] of influence + my-opinion ) / 2
) 2
set opinions replace-item my-op-ind opinions new-opinion
]
set color scale-color blue sum opinions -5 35
]
tick
end
Hopefully that is sort of on the right track, not sure if a list will work for what you need. If you must have the variables as standalone values at each tick, I suppose you could convert them to a list then follow the procedure above. If you only need them for output, you could just update your unique variables as needed based on the values in the list (as long as you are consistent with the order).

Netlogo - Given an Agentset of 2+ Turtles, find the most frequent color

Given an agentset of two or more turtles, how do I find the most frequent color?
I would like to do something like that, if possible:
set my_color [mostfrequentcolor] of my_agentset
You're looking for the modes primitive (https://ccl.northwestern.edu/netlogo/docs/dictionary.html#modes):
one-of modes [color] of my_agentset
It's "modes", plural, since there could be a tie. One way of breaking the tie is to use one-of to make a random selection.
With this example setup:
to setup
ca
crt 10 [
set color one-of [ blue green red yellow ]
]
print most-frequent-color turtles
reset-ticks
end
You can make use of a to-report procedure to do this- details in comments:
to-report most-frequent-color [ agentset_ ]
; get all colors of the agentset of interest
let all-colors [color] of agentset_
; get only the unique values
let colors-used remove-duplicates all-colors
; use map/filter to get frequencies of each color
let freqs map [ m -> length filter [ i -> i = m ] all-colors ] colors-used
; get the position of the most frequent color (ties broken randomly)
let max-freq-pos position ( max freqs ) freqs
; use that position as an index for the colors used
let max-color item max-freq-pos colors-used
report max-color
end
Here are two more options, both making use of the table extension:
extensions [ table ]
to-report most-frequent-color-1 [ agentset ]
report (first first
sort-by [ [p1 p2] -> count last p1 > count last p2 ]
table:to-list table:group-agents turtles [ color ])
end
to-report most-frequent-color-2 [ agentset ]
report ([ color ] of one-of first
sort-by [ [a b] -> count a > count b ]
table:values table:group-agents turtles [ color ])
end
I'm not quite sure which one I prefer...

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

adding agentset from different agents togother into a let

my model is a network of agents connected to each other with links.
I try to create a agentset from the neighbors of an agents and their neigbors and so on (I need this to assign different values to it).
However when I create a let with the agentset in it. the agents asked to make this agentset all have their own, this is so far so good. But when I want the original agent to ask him his second line neighbors he just returns an agentset from one of this neighbors instead of the combined agentsets of all his second line neighbors
I want the neighbors to store their own neighbors into a agentset with all the neighbors from the different agents in that set.
I cant ask the let agentset to simple do turtleset current-agentset new-agentset since in a let you cant ask to let variable. So a code which would normally be set second-neighbors (turtle-set second-neighbors other-nieghbors doesnt work since I cant ask second-neighbors already in a let
I also cant make this a global or somethins since it is agent specific.
the code I have so far looks like this
ask companies [
let this-company self
let b link-neighbors
ask b [ let c link-neighbors with [self != this-company]
ask c [ let d link-neighbors with [not member? self b]
ask this-company [
set iburen b
set iiburen c
set iiiburen d
]
]
]
]
so what I want is that all the agents in the agentset c report their link-neighbors like they do now. But also store these link-neighbors into a new agentset which has all the link-neighbors of all the agents in c. like a simple i i + 1. but than with turtle-set (what I have) (what is new from the next agent asked)
the same goes for d
If I run the model now agents report different agentset almost every tick. They just pick one agentset from any of these agents instead of combining them all togother.
Here is what I think you need:
extensions [ nw ]
breed [ companies company ]
companies-own [
buren ; a list of agentsets, with one item for each "level" of neighbors
]
to setup
clear-all
; create a random network and lay it out:
create-companies 20 [ create-links-with n-of 3 other companies ]
repeat 30 [ layout-spring turtles links 0.2 5 1 ]
let num-levels 3
ask companies [
let all-neighbors other nw:turtles-in-radius num-levels
set buren (list) ; initialize to empty list
foreach range num-levels [ i ->
let neighbors-at-this-level all-neighbors with [
nw:distance-to myself = i + 1
]
set buren lput neighbors-at-this-level buren
]
]
; demonstrate how to access the levels (sorted only for display purposes)
ask one-of companies [
show sort item 0 buren ; first level neighbors
show sort item 1 buren ; second level neighbors
show sort item 2 buren ; third level neighbors
]
end
This might not be the most efficient code possible, because it goes through the list of all neighbors once for each level, but unless you have a humongous network, you should not notice.
If you really wanted to use variables like iburen, iiburen and iiiburen, you could always alias the items of the list:
set iburen item 0 buren
set iiburen item 1 buren
set iiiburen item 2 buren
...but I don't recommend it. Having your agentsets in a list should encourage you to think of your levels in a more general way.

How to get the top 10 turtles sorted by reverse in-degree centrality?

I want to get a list of top ten turtles in terms of their degree centrality. I have tried but I am not getting the required result.
In the code below, I am storing centrality in a list and then reverse sorting it. However, it is storing centralities only. I want turtles ordered in terms of their centrality. I also have tried saving turtles on the list and have used sort-by but got an error.
I also have tried to get agents using turtles with max degree centrality, but the problem arises when several nodes have the same centrality. I want to do this in an efficient manner.
globals [indeg]
turtles-own [centrality]
to setup
ca
crt 160
ask turtles [
set indeg []
fd random 15
]
ask turtles with [color = red] [create-links-to other turtles with [color = blue]]
ask turtles with [color = green] [create-links-from other turtles with [color = yellow]]
inf
end
to inf
ask turtles [
set centrality count my-in-links
set indeg lput centrality indeg
]
set indeg sort(indeg)
print "indeg"
print reverse(indeg)
print max(indeg)
end
Here are three different ways to get that information, with potentially slightly different performance and results:
to setup
clear-all
create-turtles 160 [ forward random 15 ]
ask turtles with [color = red] [create-links-to other turtles with [color = blue]]
ask turtles with [color = green] [create-links-from other turtles with [color = yellow]]
let top-10-a reverse sort-on [ count my-in-links ] max-n-of 10 turtles [ count my-in-links ]
show-results top-10-a "Top ten turtles using max-n-of:"
let sorted-turtles reverse sort-on [ count my-in-links ] turtles
let top-10-b sublist sorted-turtles 0 9
show-results top-10-b "Top ten turtles from sorted list:"
let top-10-c filter [ t ->
[ count my-in-links ] of t >= [ count my-in-links ] of item 9 sorted-turtles
] sorted-turtles
show-results top-10-c "Turtles with top ten centrality:"
end
to show-results [ turtle-list title ]
print title
foreach turtle-list [ t -> ask t [ show count my-in-links ] ]
end
The first (method "a") and most obvious is to use NetLogo's max-n-of primitive. That primitive gives back an agentset (not a list), so if you want an agentset, that's the way to go.
Your question seem to indicate that you ultimately want a list of turtles sorted by decreasing centrality, so you have to use reverse sort-on [ count my-in-links ] on the result of max-n-of, which is what I'm doing above.
Another approach (method "b") would be to sort all turtles by their centrality, store the resulting list in sorted-turtles variables and then take the first 10 of that. That method is a bit more intuitive but could be slower than the max-n-of method since it has to sort the whole list. Depending on how many turtles you have, however,the difference could be negligible.
One thing the first two methods have in common is that the ties are broken randomly. This means that if you have, let's say, three turtles that have a centrality worthy of position number ten in your top ten, you'll only get one of those. (Given the way you construct your network in the example from your question, this is very likely to happen.) If you want your top ten to potentially include more than 10 turtles in case of equality, you need to use method "c".
The last method sorts the whole, look at the centrality of the tenth turtle in that list, and filters the list to keep only the turtles with centrality greater or equal to that one.