I'm doing a model of some chains of cells (as part of a larger DNA string model). They wiggle around on screen, and when they wiggle so much, that they come close to a cell of the same type in the same string, they must create a link with that cell.
Code below.
It kinda works.... But after I introduced the linking behavior described above, the string breaks into pieces after a short while. I can't figure out why :-) Any ideas?
Thanks,
Palle
breed [cells cell]
cells-own [paired?]
globals [chains]
to setup
clear-all
set chains []
addchain
reset-ticks
end
to go
foreach chains [c -> movechain c]
ask cells [if any? other cells-here with [label = [label] of myself and paired? = false] [
let makker one-of other cells-here with [label = [label] of myself and paired? = false]
create-link-with makker [tie]
set color red
set paired? true
ask makker [set color red set paired? true]
print word label " was found!"
]]
tick
end
to addchain
set chains lput makechain chains
end
to movechain [mylist]
let antalfollowers length mylist - 1
let i antalfollowers
repeat antalfollowers [
ask item i mylist [
move-to (item (i - 1) mylist)
]
set i i - 1
]
ask first mylist [
right random-float wigglefactor
left random-float wigglefactor
fd 1
]
end
to-report makechain
let mylist []
let text "MGIVEQCCTSICSRYQ"
let startx random-xcor / -3
let starty random-ycor / -3
let i 0
repeat length text [
create-cells 1 [
set color green
set shape "circle"
set label item i text
set paired? false
set mylist lput self mylist
setxy startx + i * .75 starty + i * .75
]
set i i + 1
]
report mylist
end
OK - I finally figured out what's going on. This was hard to see. The tricks I used
in order to see it are listed at the bottom of this post.
In the case of a single strand of synthetic DNA floating around,
when two cells of the same type hit and stick, at that point there will
be a loop of all the cells that were between the moving cell and the
cell that got run into in the list of the sequence of cells.
What you need to do is to:
(a) take the cell that just got run into and link it and tie it to the moving
cell, making the moving cell the MASTER of the link [tie]. You do that
already.
(b) remove the cell you just made a SLAVE from the list of cells your code
has to move, because it will now be moved automatically when the master cell
moves.
AND ... importantly ...
(c) repeat steps (a) and (b) for EVERY cell on the list in positions between
the two cells that just collided and stuck.**
That will effectively freeze the configuration of the entire loop and make it
into a single large unit that will move as one unit when the master cell is
moved by your code.
The User Manual states in the subsection on TIE in the section on LINKS:
When the root turtle turns right or left, the leaf turtle rotates
around the root turtle the same amount as if a stiff were attaching
the turtles. When tie-mode is set to “fixed” the heading of the leaf
turtle changes by the same amount.
I think that you do want to set tie-mode to FIXED so the whole cluster will rotate when the master cell rotates.
I think, but have not looked at it, that this algorithm will work even if the linked cell is the very first or very last one on the chain. Better check it though. Maybe the cell that should be the MASTER is the one that got hit, not the one doing the moving.
In the case of two different strands of DNA intersecting,
basically forming an X, or more complicated cases ... I leave it up to you to figure out what you want the larger connected structure to do, and how hit should move. Do BOTH of the leading cells of each strand tug on it at once? Do you need to shut off one of them so there is only one cell moving the crowd? Will you need to change your code that moves the chain to insert one of the chains entirely into the middle of the other chain on the list that moves them in sequence? I don't know!
By the way, to figure this out, I had to:
slow down the motion and
set the color of the cells to [0 255 0 125] which is a half-transparent green
so I could see through them and see through them overlap, and
use the "watch" feature of the Inspector to follow one of the cells I knew
was going to get linked up, and
use the slider in the inspector to zoom up as far as it would go, and
put a 500 millisecond "wait" in side the innermost loop of the motion.
I'm working on your question and have made some progress -- at least I have a revision of your code with some troubleshooting additions to it, and a revision of the Interface. I can't figure out how to attach a model here, or an image of the view you will see when you run it, so I posted the full model and a PNG file in the netlogo-users Google Group.
The revisions do not fully answer your question about how to solve the breaking up of the chain, but they provide a reproducible version of the model that you can be sure will break at step 746 and that you can turn on dense printing and slow action and watch what is going on with attempted moves after that.
Maybe if we both look at that it will be obvious why this is breaking.
One thing I think may be happening is that, once two cells link and tie, your move algorithm no longer is the correct logic for how the knotted chain should move.
Here's the changes that I made:
I added a random-seed command in setup so that the model can be repeatedly run with exactly the same choices in random variables, so we can both look at the results.
I added a "verbose?" switch on the Interface to turn on or off detailed printing of what's going on.
I added a "clear-stop" button that will allow the "stop" commands I put in the model to stop the running using a stop-requested? flag, which the code sets and this button resets so that "go" and "one step" work again after a stop and the ticks counter keeps on incrementing.
I added a msec-per-tick slider to put a fixed number of milliseconds at the end of the go step so the model will run at a speed that is usable for debugging. I don't know how other people can do it -- when I try to use the built-in slider at the top of the interface to control speed, either it's way too slow, or it's way too fast, and I can't seem to be able to tweak it to just right. So I added this kludge.
I guessed what limits you had on your wigglefactor slider on your interface and made one that goes from 0 to 90 (degrees). It works ok and reproduces your bug.
I added some additional tests to prevent the two C-cells that are adjacent in your choice of cells from linking to each other when they discover, as they do sometimes, that they are on the same patch. With a random seed of 23456 your original code ties its own CC adjacent pair together in tick 2 for instance.
(
Here's the revised code, and comments as to how to use it are in the posted model (in netlogo-users) and below after the code as well.
breed [cells cell]
cells-own [paired?]
globals [
chains
stop-requested? ;;//////////////////////////////////////////////////
]
to setup
clear-all
;; random-seed 12345 ;; /////////////// breaks at either step 35 or 45 ////
;; random-seed 23456 ;; ////////////////// ties its own CC in tick 2 ///
random-seed 34567 ;; /////////////////// ties own cc in tick 84 , ties C at 746 and breaks in 6 steps
;;// wow -- it SNIPS TSIC out of the middle of the chain!! snips out CTIS, turtles 7 8 9 and 10
;; cell 6 C is directly followed by cell 11 -- also C
set chains []
addchain
set stop-requested? FALSE ;; ////////////////////////////////////////
reset-ticks
end
to go
if stop-requested? [ stop ] ;;////////////////////////////////////////////
foreach chains [c -> movechain c]
ask cells [if any? other cells-here with [label = [label] of myself and paired? = false
and who != [who] of myself + 1
and who != [who] of myself - 1
] [
let makker one-of other cells-here with [label = [label] of myself and paired? = false]
create-link-with makker [tie]
set color red
set paired? true
ask makker [set color red set paired? true]
print ( word label " was found at tick " ticks)
set stop-requested? TRUE ;;/////////////////////////////////////////////
]]
wait ( msec-per-tick / 1000 ) ;;////////////////////////////////////////
tick
end
to addchain
set chains lput makechain chains
end
to movechain [mylist]
if verbose? [print ( word "\n\nin code at tick " ticks " starting movechain") ];;//////////////
;;if verbose? [ show mylist ]
let antalfollowers length mylist - 1
let i antalfollowers
repeat antalfollowers [
ask item i mylist [
if verbose? [
;;print (word " asking item " i " on mylist to move to item " (i - 1) )
let mover [label] of item i mylist
let moveto [label] of item (i - 1) mylist
let mover-color [color] of item i mylist
let moveto-color [color] of item (i - 1) mylist
;; BLUE one moves TO the YELLOW ONE at the end of this second
print (word " move " mover " to " moveto )
ask item i mylist [set color blue set shape "square" set size 2]
ask item (i - 1) mylist [set color yellow set shape "square" set size 2]
display
wait 4
ask item i mylist [set color mover-color set shape "circle" set size 1]
ask item (i - 1) mylist [set color moveto-color set shape "circle" set size 1]
display
]
move-to (item (i - 1) mylist)
;;print word "just moved follower " i ;;//////////////////////////
;; wait 0.1 ;;////////////////////////////////////////////////////
]
set i i - 1
]
ask first mylist [
right random-float wigglefactor
left random-float wigglefactor
fd 1
]
end
to-report makechain
let mylist []
let text "MGIVEQCCTSICSRYQ" ;; NOTE - this has a repeat of CC in it which SOMETIMES gets tied (23456 tick 2)
let startx random-xcor / -3
let starty random-ycor / -3
let i 0
repeat length text [
create-cells 1 [
set color green
set shape "circle"
set label item i text
set paired? false
set mylist lput self mylist
setxy startx + i * .75 starty + i * .75
]
set i i + 1
]
report mylist
end
to clear-stop ;;////////////////////////////////
set stop-requested? FALSE ;;////////////////////////////////
end ;;////////////////////////////////
Anyway, here's how to run it to reproduce the problem and examine it
in fine detail very closely.
WHAT IS IT?
model of DNA in motion modified for troubleshooting. When a "C" cell
touches another "C" cell in step 746, and sets a link between the two
C cells and ties them to move as one, the algorithm for motion
breaks somehow. This may help figure out why,
HOW IT WORKS
This has added to it a msec-per-tick slider, default 50, to set the
display speed about right if you leave the usual speed slider at the
very top in the middle (normal).
I also added a button ("clear stop") and a switch ( verbose?)
normally off. With verbose? ON, the model runs very very slowly and
color codes which cell is about to move to which cell ( blue is moving
to yellow ) and they both temporarily change to squares.
HOW TO USE IT
1) set msecs-per-tick to 50 2) shut off verbose?, click SETUP, click
GO. The model will run 746 ticks. ( thats with the random-seed set to
a value of 34567 in globals. )
3) After it stops at tick 746. click clear-stop.
NOTICE the CTI group at the upper right. This is logically BETWEEN the
two C-cells which have linked up. This group will be snipped-out of
the moving DNA It has who numbers 7, 8, 9 and 10 as you can see by
inspecting it.
4) click one-step 6 times to advance to where you can see more clearly
that the two groups have become separate. Then turn on verbose? and
click one-step once to watch the gory details with a 4 second pause
between cell-moves and the running commentary in the Command Center
telling which cells are about to move.
Related
We have a forest and randomized initial point of the fire set up, but the code fails to "ignite" (a function). Our goal is to have a hex cell aggregated model that can spread fire. Overall we want a forest fire that is more realistic by using hex cell aggregation.
Im positive that there is an issue with the eligibility or ignite function. Any help would be greatly appreciated! :)
CODE:
globals [
initial-trees ;; how many trees (green patches) we started with
burned-trees ;; how many have burned so far
switches ;; a list containing the number of switches that are on ;;[So this is the start of the weird hex cell aggregation approach, if you don't wanna use
eligibles ;; a list of cells which are eligible to be ignited ;; it that's all good, you just gotta delete like every instance of the words eligible,
] ;; switches, and all of the read-switches stuff below and on the interface and get it to run]
;; The "switches" list is used so a cell can quickly check its live
;; neighbors count against the six switches without having to actually
;; inspect the switches one by one. If the user flips a switch,
;; the list will be out of date, which is why we ask the user to
;; press the SETUP or READ-SWITCHES buttons after changing switches.
;; ;;[I figured that I'd include this from hex cell aggregation for easy potential reference]
;; The "eligibles" list is used so that when we are trying to decide
;; what cell will become alive next, we don't have to check every
;; cell. The list contains only those cells we know are eligible.
;; Every time a cell becomes alive, we remove it from the list.
;; We must also check that cell's neighbors to see if they need
;; to be added or removed from the list.
breed [cells cell] ;; used to define cells ;;[From hexagonal model examples]
breed [fires fire] ;; bright red turtles -- the leading edge of the fire ;;[From OG model]
breed [embers ember] ;; turtles gradually fading from red to near black ;;[From OG model]
cells-own [ ;;[All of cells-own is from hexagonal model examples]
hex-neighbors ;; agentset of 6 neighboring cells
live-neighbor-count ;; used to store a count of red neighbors
eligible? ;; used to see if cells are eligible for ignition or not
]
to setup
clear-all ;; clears grid
set-default-shape turtles "hex" ;; sets turtle shape to hexagonal ;;[Make sure to import the hex turtle shape from the library in Tools>"Turtle Shape Editor" first]
;; ask turtles with [(random-float 100) < density] ;; random selection from density
;; [ set color green ] ;; sets patch color to green
ask patches with [(random-float 100) < density] [ ;;[For the density parameter]
sprout-cells 1 [ ;;[For turtle creation]
set color green ;;[Grid color like the OG model]
set eligible? false
if pxcor mod 2 = 0 [ ;; if patch column is even, ;;[For converting the square grid to hexagonal]
set ycor ycor - 0.5 ;; shift it down by 0.5
]
]
]
ask cells [ ;;[Everything from here...]
ifelse pxcor mod 2 = 0 [ ;; setup for hex-neighbor agentsets
set hex-neighbors cells-on patches at-points [[0 1] [ 1 0] [ 1 -1]
[0 -1] [-1 -1] [-1 0]]
][
set hex-neighbors cells-on patches at-points [[0 1] [ 1 1] [ 1 0]
[0 -1] [-1 0] [-1 1]]
]
] ;;[...to here for hex-neighbors]
;; set tree counts
ask one-of turtles with [color = green] [ ;;[This can be moved to the go function and scrapped for a better approach if you want,
set color red] ;; just wanted to demonstrate that a random single hex could be picked to start the fire]
set initial-trees count turtles with [color = green];; counts the number of trees ;;[I felt like keeping counters for both of these but you can always remove/change them]
set burned-trees 0 ;; counts the number of burned trees
reset-ticks
end
to go ;;[Here's truly where all the problems lie haha]
if not any? turtles ;; either fires or embers
[ stop ] ;; ends simulation
ask fires ;; otherwise, continue
[ ask hex-neighbors with [color = green] ;;[I tried a number of approaches here to no avail, there are probably tons of ways to do this]
[ ignite ] ;; burn them
set breed embers ] ;; set them to fading burnt color
fade-embers ;; calls aesthetic function
tick
end
to ignite ;; patch procedure, creates fire ;;[This also is where things kinda ground to a halt for me lol]
set eligible? false ;; changes cell state
set eligibles remove self eligibles ;; removes cell from list
ask hex-neighbors [ ;; checks neighbors
set live-neighbor-count live-neighbor-count + 1 ;; adds to live neighbor count
if live-neighbor-count = 6 [ ;; if six neighbors active
ask patches [ ;; [sprout-fires only
sprout-fires 1 ;; works for patches]
[ set color red ] ;; sets cell color to red
]
]
update-eligibility ;; call for eligibility check
]
set pcolor black ;; sets patch color to black ;;[This needs to be affecting the turtle color but that creates problems I think lol]
set burned-trees burned-trees + 1 ;; adds to count of burned trees
end
to update-eligibility ;; cell procedure
ifelse eligible?
;; case 1: currently eligible
[
if not member? live-neighbor-count switches [ ;; checks if cell is in live count
set eligible? false ;; since not, change cell state
set eligibles remove self eligibles ;; and remove cell from list
]
]
;; case 2: not currently eligible
[
;; the check for hidden? ensures the cell isn't already alive
if hidden? and member? live-neighbor-count switches [ ;; [potential need ;;[This is right where the hex cells aggregation approach became too much for me lol,
set eligible? true ;; for use of hidden] ;; when everything got into hiding cells (I don't think the model should use hide/show)]
;; The order of the list doesn't matter, but in NetLogo
;; (as in Logo and Lisp generally), FPUT is much much ;;[This is directly from the hex cells aggregation example I think]
;; faster than LPUT.
set eligibles fput self eligibles ;; puts cell at start of list
]
]
end
to read-switches ;;[Admittedly I never got around to understanding how this works too well but somehow it's
set switches [] ;; more efficient, definitely might not be necessary though]
if one-neighbor? [ set switches lput 1 switches ]
if two-neighbors? [ set switches lput 2 switches ]
if three-neighbors? [ set switches lput 3 switches ]
if four-neighbors? [ set switches lput 4 switches ]
if five-neighbors? [ set switches lput 5 switches ]
if six-neighbors? [ set switches lput 6 switches ]
ask cells [
set eligible? hidden? and member? live-neighbor-count switches
]
set eligibles [self] of cells with [eligible?]
end
;; achieve fading color effect for the fire as it burns
to fade-embers ;; function for fading color of cells to show death ;;[This would be great to keep from the OG model but if it causes any issues you can delete it]
ask embers
[ set color color - 0.3 ;; make red darker
if color < red - 3.5 ;; are we almost at black?
[ set pcolor color ;;[I think this is where there's a problem of patches versus turtles]
die ] ]
end
We tried to take out the eligibility of ignition since we really don't need it, still won't run :(
We tried to redo the code of 'to go' and 'ignite' still won't budge.
As you transitioned from a patch fire model to hex cells using turtles, in you ignite procedure, should you have cells hatching fires instead of patches sprouting fires?
I'm new to NetLogo and I'm trying to create 2 sub-breeds (denoted by different shapes) within each breed for 2 breeds total (i.e. sharks and fishes). The chunks of code work as expected when ran individually, however, when running both chunks the first sub-breed of the fishes does not seem to initialise in the interface tab. For some reason the initialisation of the shark breed seems to interfere with the initiation of the fishes breed.
Any idea what i'm doing wrong? Code below.
; Create the agents
breed [sharks shark]
breed [fishes fish]
; Create the agents' variables
fishes-own
[
x0
y0
]
globals
[
species
species-f
]
to setup
; Always start with this
clear-all
reset-ticks
; Create sharks and species
create-sharks N-sharks ; N-sharks is a slider
[
set color blue
setxy random-xcor random-ycor
set species N-sharks
ask sharks
[
set shape "default"
set size 2.5
]
ask sharks with [who >= (species * (1 / 2))]
[
set shape "square"
set size 2
]
ask sharks with [who < (species * (1 / 6))]
[
set shape "star"
set size 3
]
] ; End create sharks and species
; Create fishes
create-fishes N-fishes
[
setxy random-xcor random-ycor
set x0 xcor
set y0 ycor
set species-f (N-fishes * species-ratio)
ifelse who <= species-f
[
set shape "sheep"
set size 5
]
[
set shape "cow"
set size 3
]
set color white
] ; End create fishes
end
There seem to be a number of misunderstandings about what code is run when by NetLogo, and what some pieces of code do: when you use create-turtles *number* [*commands*] (or with breeds, as in your case), commands is run once by every turtle being created (first the new turtles are created, then they run the commands in turn).
That means that every time you use ask sharks within the create-sharks' command block, every new shark will ask all other sharks to set shape and size. For example, if you create 100 sharks, instead of setting the shape and size only once you are doing it 10,000 times (100 * 100).
So you need to put all those commands out of their respective create-<breed>'s command blocks; for example:
create-sharks N-sharks [
set color blue
setxy random-xcor random-ycor
]
ask sharks [
set size 2.5
]
ask sharks with [who >= (species * (1 / 2))] [
set shape "square"
set size 2
]
ask sharks with [who < (species * (1 / 6))] [
set shape "star"
set size 3
]
This is still improvable code, but it shows how to achieve exactly the same thing by doing it once and not doing it N-sharks ^ 2 times.
A better way to do it is to bring those commands back inside the create-<breed>'s command block, but letting each agent carry out the task for itself only. That is, without using ask sharks but using ifelse, so that each shark will check its own condition:
create-sharks N-sharks [
set color blue
setxy random-xcor random-ycor
(ifelse
who >= (species * (1 / 2)) ; the first condition
[set shape "square" set size 2]
who < (species * (1 / 6)) ; the second condition
[set shape "star" set size 3]
; else
[set size 2.5])
]
All of this applies to the other breed too.
It is generally said that using who is a sign that the code should be improved, but let's not focus on this now.
You will have noticed that I omitted the part where you set species N-sharks. This is because I think there is another misunderstanding here and it is not clear to me what you wanted to do: species (such as species-f for the other breed) is a global variable. You are basically asking each of the 100 sharks (again, 100 for example) to do the same thing: set the value of a global variable to equal the value of another global variable. In this case, you are asking each shark to set species 100. This seems very unnecessary, especially considering that N-sharks is a slider used for setup and thus probably won't be changed during the simulation (which means that there is probably no need to store the current value of N-sharks as a separate global variable).
Why are you basing the repartition of your sub-breeds on the value of species? What do you want species to represent? Is it correct for it to be a separate variable from N-sharks? If yes, then it is not clear what is its point; if no, then it can be eliminated.
You need to make sure that whatever you wanted to do with N-sharks & species, and with N-fishes and species-f, is better reflected in your code.
Also because I think this is the reason why your first fish sub-breed isn't showing. First of all, what is species-ratio? It is not present in your example, but it seems to be relevant for your question. In any case, if your first fish sub-breed isn't showing, it means that there is no fish who satisfies the condition who <= species-f.
This doesn't surprise me. who numbers are progressive for turtles: if you create 15 sharks and later you create 10 fish...
... the oldest shark will have who = 0
... the youngest shark will have who = 14
... the oldest fish will have who = 15
... the youngest fish will have who = 24
As you can see in this example, there is no fish for which who <= N-fishes (where N-fishes = 10). Let alone that in your case you set species-f (N-fishes * species-ratio) and, although you didn't tell what species-ratio is, I imagine it is a value between 0 and 1 - thus making the value of species-f even smaller.
The problem is that you are using who to determine your fishes. To quote the Netlogo programming guide: "Who numbers are assigned irrespective of breeds. If you already have a frog 0, then the first mouse will be mouse 1, not mouse 0, since the who number 0 is already taken."
As such, you need to take the number of sharks into account for determining the cutoff point for your fish species
set species-f (N-fishes * species-ratio) + N-sharks - 1
One other comment I have on your code is that you use the following structure:
create-sharks N-shark [
ask sharks [...]
]
Every shark executes the entire command block of create-sharks. That means that every shark asks every shark to do something. Thus follows that every shark sets their shape to default N-shark times.
It is much more efficient to use one of the following constructions
create-sharks N-shark [...]
ask sharks [...]
or
create-sharks N-shark [
if <condition> [<reshape-self>]
]
I'm trying to load data from R to Netlogo. I always get the error
Cannot move turtle beyond the worlds edge.
error while turtle 8 running SET
called by procedure LOAD-DATA
called by procedure SETUP
called by Button 'Setup'
I defined the world edge
let minworldx r:get "min(dataTurtle$bcx)"
let maxworldx r:get "max(dataTurtle$bcx)"
letminworldy r:get "min(dataTurtle$bcy)"
let maxworldy r:get "max(dataTurtle$bcy)"
resize-world minworldx maxworldx minworldy maxworldy
The turtles are defined as follows
set dataTurt r:get "dataTurtle" ; transfers data to Netlogo
print dataTurt ; just to test
ask turtles ; reads in data to the variables
[ set color 14
set heading 1
set xcor item who Item 1 dataTurt
set ycor item who Item 2 dataTurt
set label item who Item 0 dataTurt
set P_FertSpace 2000 ; just a value test value
]
How can I ensure that all turtles that I create get the assinged data?
The loop is stopping because there's an error. The error message tells you that the error is because you are trying to put a turtle in a place that doesn't exist.
Does this fix it?
let minworldx floor r:get "min(dataTurtle$bcx)" - 1
let maxworldx ceiling r:get "max(dataTurtle$bcx)" + 1
let minworldy floor r:get "min(dataTurtle$bcy)" - 1
let maxworldy ceiling r:get "max(dataTurtle$bcy)" + 1
resize-world minworldx maxworldx minworldy maxworldy
I have used floor and ceiling to round down and up respectively, and then added or subtracted 1 for extra safety. This should make sure the turtles don't get positioned outside the world boundaries.
I'm new at NetLogo. I'm not new at agent-based modeling. Now and then I see people saying NetLogo is so fun and easy that I'm giving it a try.
I'm stuck at square 1, can't figure out code for messaging between agents, scheduling actions for subsets of agents, other basic ABM things.
I'm working on a majority rule election model in which the turtles are voters with randomly placed x,y coordinates. Candidates (a new breed) make promises in x,y plane, the winning candidate is the one preferred by (closer to) more agents.
The patches play no role at all, except the spatial graph seems to require use of a grid
I'm having trouble in the updating of candidate positions. I conceived this as follows: Remove a 'winner' agent from the candidate agentset, tell the other candidates to adjust, then put the winner back in the agent list and see who wins in the next time.
I believe the following is close to minimum reproducible example. Please look at adjustOfferings. (Sorry, I left in a lot of show statements, otherwise can't tell what's going on.)
; Paul Johnson
; 20160801
breed [candidates candidate]
globals[
N
D
]
; turtles are voters, Euclidean-based preferences. Use
; built-in 2d coordinates for ideal points for now,
; need to learn how to create weighted multi-dimensional
; preferences later
turtles-own
[
name
]
to setup
ca ; clear all
reset-ticks ; time start 0
set N 100
; N voters with random x,y ideal points
create-turtles N
[
setxy random-xcor random-ycor
]
set D 2
create-candidates D
[
setxy random-xcor random-ycor
set shape "square"
set size 2
]
end
; collect up the votes. Don't worry about invading agent
; privacy, just measure for them
to-report election2 [choices]
let fave [min-one-of choices [distance myself]] of turtles
report fave
end
; Ask all non winners to adjust their offering
to adjustOfferings [winner]
show (word "in adjustOfferings, winner was: " winner)
let losers candidates with [self != winner]
show (word "adjustOfferings losers are: " losers)
ask losers
[
setxy random-xcor random-ycor
]
end
; ask each voter for its favorite,
; use modes to calculate the winner
to electionCycle
let theVotes election2 candidates
show (word "electionCycle: " theVotes)
let winner modes theVotes
show (word "electionCycle Winner: " winner)
adjustOfferings winner
end
to go
tick
if ticks > 1000
[
stop
]
electionCycle
end
The setup works fine, I see agents and candidates. When I hit the "Step button", I can see the election works, a winner is selected, but all candidates adjust (not just losers). Here's the console:
observer: "electionCycle: [(candidate 100) (candidate 101)
(candidate 101) (candidate 101) (candidate 100) (candidate 101)
[snip]
(candidate 100) (candidate 101)]"
observer: "electionCycle Winner: [(candidate 100)]"
observer: "in adjustOfferings, winner was: [(candidate 100)]"
observer: "adjustOfferings losers are: (agentset, 2 turtles)"
Appears to me this is the source of error:
let losers candidates with [self != winner]
The winner is still in losers after that.
I realize now you can't actually run this without the rest of the NetLogo file. What is your custom here for providing the fully runable example? Can I point you at a file on a website? http://pj.freefaculty.org/scraps/majority.nlogo. I could put this in GitHub or someplace else if you prefer.
I appreciate your advice.
The problem is indeed with the line you suggested. Both agents report true for the condition [self != winner], but why is it the case. Look at how you create and pass the winner variable to the function. You create it by using the modes primitive, which is a good idea. But modes will report you a list with one element. The problem is that you pass this list directly to your adjustofferings function. This means, the agents than compare [self != [(candidatexy)]]instead of [self != (candidatexy)] (mind the additional brackets in the first example, indicating the list).
To solve the problem, you have to extract the winner agent from the list by using the first primitive, which reports you the first item of a list. You only have to add this to the line, where you define the winnervariable: let winner first modes theVotes
I am trying to restore an initial(back to its first state) context of turtles and link after killing one turtle.
I have been trying the solution from http://ccl.northwestern.edu/netlogo/docs/nw.html, but somehow it doesn't work.
Below is my code
to cycle
if Measure = "Efficiency of network"
[ ;store node and link
nw:set-context turtles with [ shape = "circle" ] links with [ color = blue ]
show map sort nw:get-context
set old-turtles item 0 nw:get-context
show old-turtles
set old-links item 1 nw:get-context
show old-links
;start process
process-performance
]
end
to process-performance
if NumberOfNodes = 1
[file-open "1node.txt"
while [not file-at-end?]
[
;calculate initial performance value
set initial nw:mean-path-length
show initial
let nodeseq read-from-string (word "[" file-read-line "]")
show item 0 nodeseq
ask turtle (item 0 nodeseq) [ die ]
update-plots
;calculate new performance value
set final nw:mean-path-length
show final
set result (1 - (final / initial)) * 100
show result
nw:set-context old-turtles old-links
show map sort nw:get-context
]
file-close
]
end
I have been using "nw:set-context old-turtles old-links" in the documentation from netlogo but it seems that the original turtle and link context I store in "old-turtles old-links" will be purposefully altered no matter how I store them. I am thinking if [die] function alter the agent-set stored? The old-turtles and old-links are progressively smaller in size as I kill the node. I did not store the renewed context of the nw back to old-turtles and old-links.
Or does anyone have other ways in storing the old agent-set and link and restoring back to its original network structure?
Thanks for reading through.
Killing a turtle does indeed remove it from all agentsets, so restoring the context won't bring it back. You might try removing the turtle from the context rather than killing it. You could hide the turtle and its links to reproduce the visuals of killing it as well. This would be something like:
...
let target-turtle turtle (item 0 nodeseq)
ask target-turtle [
hide-turtle
ask my-links [ hide-link ]
]
nw:with-context (remove turtle (item 0 nodeseq) old-turtles) old-links [
update-plots
;calculate new performance value
set final nw:mean-path-length
show final
set result (1 - (final / initial)) * 100
show result
]
...
This way, the turtle is removed from the context for the purpose of your calculations, but not killed, so its structural information is remembered. nw:with-context handles storing and restoring the context for you, but this code works just as well without it (you just have to restore the context yourself).