Assigning random variables within turtle groups - netlogo

I have a dynamic number of groups of turtles (slider controlled, groups labeled with the variable group-id) which have an associated turtles-own variable (trait-1), I am attempting to randomly assign a different value to trait-1 for each group of turtles (group-id). At the moment each individual turtle has a randomly assigned trait-1 value which varies both within and among groups, but I want it to be the same for all individuals within each group, and only vary among groups. Any help would be great!
Side note, I am using a grouping variable instead of breeds as I couldn't figure out how to make the number of breeds dynamically controllable via a slider... not sure this is possible?
turtles-own [
group-id ;grouping id, each group represents a species
trait-1 ; a trait to be assigned a score from 1 - 10
]
to setup
clear-all
set-species
end
to set-species
let n_groups num_species ;create n groups of turtles based on slider value (num_species)
foreach n-values n_groups [ ? ] [
create-turtles 3 [ ;create 3 indviduals in each group
set group-id ?
set color (group-id + 19) ; give each group a different color
set trait-1 1 + random 10 ] ;set trait-1 ranging from 1 to 10
]
ask turtles [ set label group-id ] ; show group-id
ask turtles[ ; move turtles out of the center, not really important, just to help see the turtles.
fd trait-1
]
end

Just move where you set it outside of the turtle initialization:
foreach n-values n_groups [ ? ] [
let group-trait 1 + random 10 ;set it here
create-turtles 3 [ ;create 3 indviduals in each group
set group-id ?
set trait-1 group-trait
set color (group-id + 19) ; give each group a different color
;set trait-1 1 + random 10 ] ;don't set it here
]
]

Related

Netlogo: values of same breed variables won't sum. The values are created and updated from models connected to the turtles via Levelspace

I am currently creating a Multi-level ABM using Levelspace. In the parent model I'm trying to sum the values of one variable of multiple turtles of the same breed (the number of turtles are determined by a different breeds-own variable). The variable for each turtle receives it's value from their respective child models connected via Levelspace.
Currently the parent model can receive the values from the child models. I have written a code that has a parent model turtle select particular turtles representing child models, have those selected turtles constantly update their variables totals (received from their respective child models) and display each updated total at each tick.
My problem is summing each updated child model totals into one total in the parent model that updates after each tick. Here's the code that so far:
ask turtle 0 [
if breed = Epics
[
let closteams Teams with [AsgnEpic = "Epic 1"]
foreach sort-on [who] closteams
[
the-closeteams -> ask the-closeteams [show reduce + [Value] of the-closeteams]
]
]
]
I've added a variable in the foreach block and tried to sum the totals but only received 0 as an output (see code below):
foreach sort-on [who] closteams
[
the-closeteams -> ask the-closeteams [show reduce + [Value] of the-closeteams]
let vartot sum [value] of closteams
]
Can anyone guide me on how to solve this problem?
Thanks
Rudy
----------------------------------UPDATED INFO-----------------------------------
The model has three levels consisting of several models connected by the Levelspace extension.
The top level is the parent model. The parent model is a Graphical User Interface model created with the extrawidget extension. Users enter information in this parent model to customize the model. This Graphical User Interface model sends all entered information to a second model (the first level child model) via Levelspace. The second model is where the user runs the model.
Here is the part of the setup procedure from the second model (the first child model). It creates Epics and teams (teams call their own child models (the second level child models) via Levelspace):
to setup
ls:reset
let n length TotEpics
let horizontal-interval (world-width / n)
foreach n-values n [ [i] -> i ] [ [i] ->
create-Epics 1 [
set label item i TotEpics
set color item i ColorEpics
set shape "box"
setxy (min-pxcor - 0.5 + horizontal-interval * (0.5 + who)) 15
set size 8
]
]
let o length TN1
foreach n-values o [ [i] -> i ] [ [i] ->
create-Teams 1 [
set label item i TN1
set color color
set Members item i TM1
set AsgnEpic item i Epic1
set Value []
set xcor -16
set ycor 12 + i * -7
set size 4.5
ls:create-interactive-models 1 "Problem_Solving.nlogo"
set model-id last ls:models
ls:hide model-id
]
ask Teams [
if AsgnEpic = "Epic 1" [
create-link-with epic 0
set xcor [xcor] of epic 0
set ycor [ycor - 8] of epic 0
set color blue ]
while [any? other turtles-here] [if can-move? 2 [set heading 180 fd 5 set
color blue + 2]]
if model-id = 0
[
ls:let name label
ls:let mem Members
ls:let AE AsgnEpic
ls:ask 0 [
set Number-of-Agents mem
set Epic AE
setup ]
]
if model-id = 1
[
ls:let name label
ls:let mem Members
ls:let AE AsgnEpic
ls:ask 1 [
set Number-of-Agents mem
set Epic AE
setup ]
]
;this is repeated several times with the model-id number and ask number
;increasing incrementally to accommodate multiple teams
]
reset-ticks
end
The setup procedure does not have a "clear-all" in it because "clear-all" wipes out all the information received from the Graphical User Interface parent model.
Below is the portion of the go procedure that runs the model and collects the input for the Teams "Value" variable from their respective child models:
to go
ask Teams
[
if model-id = 0 [ls:ask 0 [go] set Value lput [average-score] ls:of 0 Value
]
if model-id = 1 [ls:ask 1 [go] set Value lput [average-score] ls:of 1 Value
]
;this is repeated several times with the model-id number increasing
;incrementally to accommodate multiple teams
]
Value-of-Stories1
tick
end
So the "Value" variable of each team receives it's value from a separate Levelspace connected child models "average-score" global variable. I then sum the totals of each teams Value input every tick with the code below.
to Value-of-Stories1
ask turtle 0 [
if breed = Epics
[
let closteams Teams with [AsgnEpic = "Epic 1"]
foreach sort-on [who] closteams
[
the-closeteams -> ask the-closeteams [show reduce + [Value] of the-
closeteams]
]
]
]
end
Totaling the separate Teams "Value" totals into one number is the challenge.
There's more code then this but I believe this is the code relevant to what I'm trying to resolve.
Thanks
Rudy

Selecting an item from a list in Netlogo

I'd need to pick an object in a bag containing 20 elements with attributes c (color) and s (size). Both color and size are numbers (e.g. c= {red = 256, black = 0, ... } = {256, 0, ...}).
As in Python I'd use random.choice in numpy library, I found on the web that the corresponding function in Netlogo is the extension rnd.
Struggling along a possible solution, I did
Edited:
breed[people person]
people-own
[
ball
size
color
bag
]
to setup
create-people 5
[ set color gray
setxy random-xcor random-ycor
]
ask people[
set bag [ ] ; 0 items
]
end
To create the balls:
to create-balls
set color random 300 ; color
set size random-float 5 ; size
let this-ball self
ask one-of people [ ; ask one of people to put the ball created into the bag
set bag fput this-ball bag ; add ball to the bag
]
end
The code below should include the part of drawing:
to draw
ask one-of people [
rnd:weighted-one-of bag [ ] ; I do not know what I'd write in the brackets
]
end
As you can easily see, I've many doubts about how to implement the code.
How can I select one item from the bag depending on its size (or color)?
Can you please help me out with it?
Here is a complete model that creates people and balls as turtle agents and has 30 of the balls get chosen weighted by their size. It then opens an inspect window for the person who has chosen the most balls.
extensions [rnd]
breed [people person]
people-own [ my-balls ]
breed [balls ball]
balls-own [ chosen? ]
to setup
clear-all
create-people 20
[ setxy random-xcor random-ycor
set my-balls (turtle-set nobody)
]
create-balls 50
[ hide-turtle
set size one-of [1 2 3 4 5]
set color one-of [red white blue yellow]
set chosen? false
]
repeat 30 [draw-ball]
inspect max-one-of people [count my-balls]
end
to draw-ball
ask one-of people
[ let bag-of-balls balls with [not chosen?]
let choice rnd:weighted-one-of bag-of-balls [size]
ask choice [set chosen? true]
set my-balls (turtle-set my-balls choice)
]
end
Some things to notice:
There are NO lists in this code. There are situations where you should use lists. Common uses include memory where the order is important (eg you only want to keep track of the last 5 other people seen) or where the same agent can appear multiple times. And the list commands are very powerful. However, unless you need a list then you should use agentsets.
Each person has their own bag called 'my-balls' that contains the balls they select. That is initialised as a turtle-list as part of the setup.
I used a variable called 'chosen?' that is owned by each ball to track whether it is still in the bag for the next person to choose. Then the bag-of-balls is created only as all the balls not yet chosen.
The code for weighted random choice (when choosing from agentsets) simply has the name of the variable holding the weight as the reporter, but you could use some function such as rnd:weighted-one-of bag-of-balls [size ^ 2] if you wanted a more complicated weighting scheme.

Create links according to turtle's attributes

I have two turtle breeds (products and consumers) each with a 3-dimension list that defines their needs (consumers) and their attributes (products).
What I'd like is to have each consumer (i) look for a product that satisfies all their needs and create a link with them. If that product does not exist, I'd like them to (ii) drop the one need with the lowest value and look for a product that satisfies the other two. If that product does not exist, then I want them to (iii) look for another one that only satisfies the need with the highest value.
So say that consumer 20 has needs [0.2 0.5 0.3]. If they find a product whith exactly the same list of attributes [0.2 0.5 0.3] I want the link to take place. If there's no such product then I want the consumer to ignore the lowest value (0.2 in the example) and look for a product that has attributes [xx 0.5 0.3], where xx stands for "whatever".
Using examples from elsewhere here in SO, I have cobbled up the following code that (almost!) does the first part of the trick (i), but can't manage to do (ii) and (iii) despite multiple efforts. Would anyone have an indea on how to do this?
breed [consumers consumer]
breed [products product]
consumers-own [
needs
]
products-own [
attributes
number-buyers
]
to setup
ca
create-consumers 100 [ setxy random-xcor random-ycor]
create-products 100 [ setxy random-xcor random-ycor]
set-default-shape consumers "person"
set-default-shape products "box"
ask consumers [
set needs n-values 3 [ precision (random-float 1) 1 ]
]
ask products [
set attributes n-values 3 [ precision (random-float 1) 1 ]
]
reset-ticks
end
to go
buy
tick
end
to buy
ask links [ die ]
ask consumers [
carefully [ create-link-with one-of products with [reduce and (map = attributes [ needs ] of myself)] ] [ show "how do I find a sub-optimal product by ignoring my need with the lowest value ?" ]
]
ask products [
set number-buyers count link-neighbors
]
end
You are overthinking the full match - just check if the two lists are the same. However, the almost match is a bit more complicated. Here is a complete example model that finds the position in the list of the lowest and then checks that the other items are the same.
breed [consumers consumer]
breed [products product]
consumers-own [
needs
]
products-own [
attributes
number-buyers
]
to setup
clear-all
ask patches [set pcolor white]
create-consumers 10
[ setxy random-xcor random-ycor
set shape "person"
set color blue
set needs n-values 3 [ one-of [1 2 3] ]
]
create-products 10
[ setxy random-xcor random-ycor
set shape "box"
set color red
set attributes n-values 3 [ one-of [1 2 3] ]
]
reset-ticks
end
to go
ask consumers [buy]
tick
end
to buy ; set up as turtle procedure for testing purposes
ask my-links [ die ]
let candidates products with [attributes = [needs] of myself]
ifelse any? candidates
[ create-link-with one-of candidates ]
[ type self type " attributes: " type needs print " no matches"
let lowpoint position (min needs) needs ; note will take first if two equal min
set candidates products with
[ ((item 0 attributes = item 0 [needs] of myself) or lowpoint = 0) and
((item 1 attributes = item 1 [needs] of myself) or lowpoint = 1) and
((item 2 attributes = item 2 [needs] of myself) or lowpoint = 2)
]
ifelse any? candidates
[ create-link-with one-of candidates ]
[ print "no almost-match available" ]
]
end
I created the agentset (called candidates) of potential products to link to and then created the link. This makes the code much more readable. It also allows the if any? construction if no matches were found. And it also makes it easier to debug because you can put print statements reporting numbers of matches and similar. I recommend that you always do this if you are applying some sort of condition that restricts the choices.
Also, you have a three item list with 10 possible values for each item. This means there will be 1000 combinations. You only have 100 consumers and 100 products, so matching will be fairly rare.

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).

n-of or one-of turtles is not working as expected when working with turtles individually

I have 200 turtles which represent producers. Each turtle, has 2 variables (sales of 2 prodcuts) and they are compared to let the prodcuer know which product was the most popular, so the turtle's color changes to the color representing that product.
I defined this loop :
while [counter < 201][
ask n-of 1 producers [
if (product1sales > product2sales)
[
set color green
]
if (product2sales > product1sales)
[
set color red
]
;
set counter counter + 1]
]
I assumed each time n-of is called, one turtle is chosen, but this specific turtle will not be chosen again. I also assumed that by running the code, all the turtles must be either green or red, but some are neither green nor red since n-of is not working as I assumed. one-of is not doing what I want either. Any ideas?
Thanks
If you just ask producers it will ask all of the producers in a random order, but without repeating- if you just want all of them to make a choice between the two choices you wouldn't even need the counter.
If either product1sales or product2salesis always higher, you could also trim a little by using ifelse. See if the example below would give you what you need:
breed [ producers producer ]
producers-own [ product1sales product2sales ]
to setup
ca
reset-ticks
create-producers 200 [
setxy random 30 - 15 random 30 - 15
set product1sales random-float 11
set product2sales random-float 11
set color white
]
end
to choose
ask producers [
ifelse product1sales > product2sales [
set color green
]
[
set color red
]
]
end