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

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

Related

How do I pass lists (and other information) from the parent models global variable to it's child's model global variable in Netlogo's LevelSpace

I'm currently building a multi level ABM using Levelspace. I am also using the extrawidget extension as a frontend GUI for entering and capturing user information. The extrawidget GUI is a stand alone Netlogo model and serves as the parent model in Levelspace. Some of the captured information is stored as lists in the parent models global variables.
I am trying pass the content of the extrawidget parent model global variables (particularly the lists) to the child model's global variables. I cannot seem to find a way to accomplish this. I've tried "ls:let" in conjunction with "ls:ask" to set the child models global variable but that did not work. I used "ls:assign" but that was unsuccessful also.
I believe some kind of reporter in both the parent and child model may be the answer but I am unable to determine how to code something like that.
Could someone please assist me in solving this problem.
Thanks
Rudy
--------------------------------------------------------Follow-Up---------------------------------------------------
I discovered that ls:assign did work, "clear-all" in the child model's setup command wiped out the information in global variables. I removed the "clear-all" and can see the lists in monitors I added for the global variables but even though the lists are there I'm still getting this error message when the child model attempts to run "setup"
" Extension exception: Model 0 (Scaled Agile Simulator1.nlogo) encountered an error: ITEM expected input to be a string or list but got the number 0 instead.
error while observer running LS:ASK
called by procedure SETUP
called by procedure __EVALUATOR"
I have included the child model setup code below:
to setup
ls:reset
;clear-all
let n length TotEpics
foreach n-values n [ [i] -> i ] [ [i] ->
create-Epics 1 [
setxy -20 20
set label item i TotEpics
set Complex item i EpicCmplx
set Stories item i EpicStories
set ETime [ ]
set Tasks1 EpicTasks1
set Tasks2 EpicTasks2
set Tasks3 EpicTasks3
set Tasks4 EpicTasks4
set shape "box"
set size 8
]
]
let o length ScrumTN1
foreach n-values o [ [i] -> i ] [ [i] ->
create-Scrum-Teams 1 [
set label item i ScrumTN1
set shape "Scrum"
set color color
set Members item i ScrumTM1
set Strat item i ScrumStrt1
set AsgnEpic item i ScrmEpic1
set S-Stories 0
set Cost item i ScrumCst1
set Value [ ]
set Time [ ]
set S-Story-Size 0
set xcor -16
set ycor 12 + i * -7
set size 4.5
ls:create-interactive-models 1 "Problem_Solving_in_Networks WIP.nlogo"
set model-id last ls:models
ls:hide model-id
]
]
let b length ScrumTN2
foreach n-values b [ [i] -> i ] [ [i] ->
create-Scrum-Teams 1 [
set label item i ScrumTN2
set shape "Scrum"
set color item i Color1
set Members item i ScrumTM2
set Strat item i ScrumStrt2
set AsgnEpic item i ScrmEpic2
set S-Stories 0
set Cost item i ScrumCst2
set Value [ ]
set Time [ ]
set S-Story-Size 0
set xcor -4.5
set ycor 12 + i * -7
set size 4.5
ls:create-interactive-models 1 "Problem_Solving_in_Networks WIP.nlogo"
set model-id last ls:models
ls:hide model-id
]
]
let p length KanbanTN3
foreach n-values p [ [i] -> i ] [ [i] ->
create-Kanban-Teams 1 [
set label item i KanbanTN3
set shape "Kanban"
set color color
set xcor -18 + i * 9
set ycor -20
set size 4.5
ls:create-interactive-models 1 "Kanban3_v5_2.nlogo"
set model-id last ls:models
ls:hide model-id
]
]
All the "variables" in "set variable-name item i variables" are lists so I'm not expecting to see the error message stating "ITEM expected input to be a string or list but got the number 0 instead"
Anyone have any insights?
Thanks
Rudy
---------------------------------------------Please Disregard until further notice-----------------------------------
I've discovered some missing code in my setup command causing this "ERROR". Please disregard my question. If I run into any serious roadblocks I'll reach out.
Thanks

How to give a score when an element is pulled out from a list?

I would like to implement a part of code where agents can get a score when they pick an element from a list generated from a specific turtle.
I set
breed [playersA playerA]
breed [playersB playerB]
breed [balls ball]
playersA-own[
my-list
new_ball
score
]
playersB-own[
my-list
new_ball
score
]
to setup
clear-all
create-playersA 10
ask playerA 0 [ create-links-with other playersA ]
ask playerA 2 [ create-link-with playerA 1 ]
create-playersB 10
ask playerB 0 [ create-links-with other playersB ]
ask playerB 2 [ create-link-with playerA 1 ]
ask playersA[
set my-list []
set score 0
]
ask playersB[
set my-list []
set score 0
]
end
to go
let selected nobody
let team-player nobody
set selected one-of turtles with [breed=playersA or breed=playersB]
ifelse [breed = playersA] of selected[
ask selected [
set size [count link-neighbors] of self
show size
]
create-balls 1[
hide-turtle
]
]
[ ask selected [
set size [count link-neighbors] of self
show size
]
create-balls 1[
hide-turtle
]
]
set team-player link-neighbors with [breed = playersA]
ask team_player [
set my-list lput my-ball my-list
]
end
The above code should select on random turtle and add a new ball to its neighbours list. What I would need is probably a counter that can compute how many balls were shared between players.
Could you please help me to figure out with it?
Thanks
The code you posted has many problems that prevent it from passing error-checking in the editor. Some of these produce surprising error messages that don't even make sense, and they happen because the logic mixes contexts -- that is, some commands make sense for the "observer" level, some require being in a "turtle" context, etc.
I think you are trying to do too much at once, and trying to add a counter to code that already does not work. First you have to fix the code you have and then you can see where to add a counter.
You absolutely must understand how the unique agent id number "who" works. Each turtle has a unique who number assigned, starting with zero. It doesn't matter whether the breed of turtle is playerA or playerB or a ball, it will have a unique number. Once you create your first 10 turtles, of the PlayerA breed, they will have who numbers 0 through 9. Then, when you create the next 10 turtles, of PlayerB breed, they will get assigned who numbers of 10 through 19. If you then create a ball, say, it will have a who number of 20.
So there will never be a PlayerB with a who number of 0 or 1 or 2. Those numbers will already be used by PlayerA. Your setup will crash with the error:
playera 0 is not a PLAYERB error while observer running PLAYERB
called by Command Center
Even with just PlayerA, it is not clear what kind of network you want to build in the setup code. Why would everyone link to player 0, but then also add a single link between player 1 and player 2? Since players only "see" their linked team-mates, only player zero will see everyone else. Other players will have only one or two link-neighbors, so they will never update everyone else's my-lists.
create-playersA 10
ask playerA 0 [ create-links-with other playersA ]
ask playerA 2 [ create-link-with playerA 1 ]
Anyway, I would suggest that you get this much working correctly before trying to add counting.
I don't think you can do that by just looking at the code. You need to get rid of as much complexity as you can, and then use shapes, colors, and numerous print statements to see whether each command is doing what you think it should do. Complex working code almost always evolves from simple working code.
So get rid of PlayersB entirely ( comment out the code ), only create 5 players A, and change the colors and shapes as you process each step to confirm that it is working. The editor lets you use ctrl-; to comment out entire blocks of code, or un-comment them at once, so comment out everything you possibly can while you are getting one step to work, then uncomment the next section, get that to work, etc.
When you finally get everything working, you can comment out all your print statements that you used in development.
Anyway, I refactored your code, added many comment, and added many print statements, and finally got it to run. If you run just setup and look at the view, you will see what I mean about the network. ( I shut off wrapping in the view so the network looks right.)
Here's my revision of your code. It prints out what is in each player's my-list after each step, so you can see at a glance if it is doing what you want, or not. ( It's not.)
I added the who numbers as a label to each player in the view so you can see what I mean.
It produces helpful output like:
let's confirm that the lists have been updated. Here's the my-lists
for playersA [[5 5 5 5 10] [0 0 0 0 0] [0 8 8] [0 0] [0 9]]
Get the setup step to work correctly and generate the network you want before you even try to fix the go section.
breed [playersA playerA]
breed [playersB playerB]
breed [balls ball]
playersA-own[
my-list
new_ball
score
]
playersB-own[
my-list
new_ball
score
]
to setup
clear-all
;; for debugging, only create 3 players and inspect the results to confirm it's working as you intended
;; use labels to see player numbers in the view
create-playersA 5 [ set size 1 set color blue set shape "square" setxy random-xcor random-ycor set label who]
ask playerA 0 [ create-links-with other playersA [set color blue]]
ask playerA 2 [ create-link-with playerA 1 [set color red]]
create-playersB 5 [ set size 2 set color yellow set shape "person" setxy random-xcor random-ycor set label who]
; comment out this code until create-playersA is working properly
; ask playerB 0 [ create-links-with other playersB ]
; ask playerB 2 [ create-link-with playerA 1 ] ;; copy-and-paste error? link with playerB intended?
ask playersA[
set my-list []
set score 0
]
ask playersB[
set my-list []
set score 0
]
reset-ticks
end
to go
let selected nobody
let team-players nobody
let hot-ball nobody
set selected one-of turtles with [
breed = playersA
;; or breed = playersB ;; always select one of playersA for debugging this code
]
print ( word "At point 1, we selected turtle " [who] of selected " with breed " [breed] of selected)
;; we're still in the observer context here
ifelse [breed = playersA] of selected [ ;; by mentioning breed, we shift into a turtle context silently
print ( word " entering the TRUE part of the if-else statement " )
ask selected [
set size [count link-neighbors] of self
print ( word "at point 2 we set selected player's size to " size )
]
create-balls 1 [
set shape "circle" set size 3 set color blue set label who
set hot-ball who
; hide-turtle ;; for debugging show it so you can click on it and inspect it
print ( word "at point 3 we set created a blue hot-ball with who= " hot-ball )
]
;; it seems you want to update the selected turtle's my-ball variable here with a reference to the ball just created??
print " at point 4 we should set selected agent's my-ball to the ball we just made..."
ask selected [
set new_ball hot-ball
]
print (word " Confirming that selected player got the hot-ball " [new_ball] of selected )
;; ask ball hot-ball [ set hidden? true ]
;; this set of code seems to apply only when selected turtle is one of playersA, so it was moved INSIDE that ask-selected code
;; and put inside another ask selected [ ] context
ask selected [
set team-players link-neighbors with [breed = playersA]
print (word "At point 5, For selected player " who ", here is the team-players agent set :" )
print (sort team-players) ;; using "sort" here just to convert an agent set to a list for display
]
print " ------------- about to ask team-players to update their my-lists and change to triangles ---"
ask team-players [
set shape "triangle" set size 3 ;; to see at a glance that everyone was processed
set my-list lput new_ball my-list
print "... updated one my-list"
]
print " let's confirm that the lists have been updated. Here's the my-lists for playersA "
print map [ i -> [my-list] of i ] sort playersA ;; using "sort" to convert agent-set to a list
print (word "At the end of the go step, we have this many balls: " count balls)
]
;; else we should have breed != playersA
[
error " we should only be looking at one of playersA here for testing" ;; for debugging
]
;; tick
end

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.

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.

Assigning random variables within turtle groups

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
]
]