So, this is a part of a task I have to get done: ''Create a version of this model that rewards successful strategies by allowing them to reproduce and punishes unsuccessful strategies by allowing them to die off.''
But the thing is I can't get it to work, it displays an error every number of ticks, this is the code I have so far (I removed the commands of scores, dying and reproducing, so this is the pure code you could say) what should I add to make it work?
Help would be much appreciated, thanks!
This is the code
globals [
;;number of turtles with each strategy
num-random
num-cooperate
num-defect
num-tit-for-tat
num-unforgiving
num-unknown
;;number of interactions by each strategy
num-random-games
num-cooperate-games
num-defect-games
num-tit-for-tat-games
num-unforgiving-games
num-unknown-games
;;total score of all turtles playing each strategy
random-score
cooperate-score
defect-score
tit-for-tat-score
unforgiving-score
unknown-score
;;Noise
noise-active ;;turn noise on and off
noise-prob-defect ;;probability to flip a cooperate into a defect
noise-prob-cooperate ;;probability to flig a defect into a cooperate
noise-defect-true ;;Counter of times a defect turned into a cooperate
noise-cooperate-true ;;Counter of times a cooperate turned into a defect
]
turtles-own [
score
strategy
defect-now?
partner-defected? ;;action of the partner
partnered? ;;am I partnered?
partner ;;WHO of my partner (nobody if not partnered)
partner-history ;;a list containing information about past interactions
;;with other turtles (indexed by WHO values)
]
;;;;;;;;;;;;;;;;;;;;;;
;;;Setup Procedures;;;
;;;;;;;;;;;;;;;;;;;;;;
to setup
clear-all
store-initial-turtle-counts ;;record the number of turtles created for each strategy
setup-turtles ;;setup the turtles and distribute them randomly
noise-setup ;; setup of the noise variables
reset-ticks
end
;;record the number of turtles created for each strategy
;;The number of turtles of each strategy is used when calculating average payoffs.
;;Slider values might change over time, so we need to record their settings.
;;Counting the turtles would also work, but slows the model.
to store-initial-turtle-counts
set num-random n-random
set num-cooperate n-cooperate
set num-defect n-defect
set num-tit-for-tat n-tit-for-tat
set num-unforgiving n-unforgiving
set num-unknown n-unknown
end
;;setup the turtles and distribute them randomly
to setup-turtles
make-turtles ;;create the appropriate number of turtles playing each strategy
setup-common-variables ;;sets the variables that all turtles share
end
;;create the appropriate number of turtles playing each strategy
to make-turtles
create-turtles num-random [ set strategy "random" set color gray - 1 ]
create-turtles num-cooperate [ set strategy "cooperate" set color red ]
create-turtles num-defect [ set strategy "defect" set color blue ]
create-turtles num-tit-for-tat [ set strategy "tit-for-tat" set color lime ]
create-turtles num-unforgiving [ set strategy "unforgiving" set color turquoise - 1 ]
create-turtles num-unknown [set strategy "unknown" set color magenta ]
end
;;set the variables that all turtles share
to setup-common-variables
ask turtles [
set score 0
set partnered? false
set partner nobody
setxy random-xcor random-ycor
]
setup-history-lists ;;initialize PARTNER-HISTORY list in all turtles
end
;;initialize PARTNER-HISTORY list in all turtles
to setup-history-lists
let num-turtles count turtles
let default-history [] ;;initialize the DEFAULT-HISTORY variable to be a list
;;create a list with NUM-TURTLE elements for storing partner histories
repeat num-turtles [ set default-history (fput false default-history) ]
;;give each turtle a copy of this list for tracking partner histories
ask turtles [ set partner-history default-history ]
end
;;;;;;;;;;;;;;;;;;;;;;;;
;;;Runtime Procedures;;;
;;;;;;;;;;;;;;;;;;;;;;;;
to go
clear-last-round
ask turtles [ partner-up ] ;;have turtles try to find a partner
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [ select-action ] ;;all partnered turtles select action
ask partnered-turtles [ play-a-round ]
do-scoring
tick
end
to clear-last-round
let partnered-turtles turtles with [ partnered? ]
ifelse (random 100 > prob-of-staying)
[ask partnered-turtles [ release-partners ]]
[]
end
;;release partner and turn around to leave
to release-partners
set partnered? false
set partner nobody
rt 180
set label ""
end
;;have turtles try to find a partner
;;Since other turtles that have already executed partner-up may have
;;caused the turtle executing partner-up to be partnered,
;;a check is needed to make sure the calling turtle isn't partnered.
to partner-up ;;turtle procedure
if (not partnered?) [ ;;make sure still not partnered
rt (random-float 90 - random-float 90) fd 1 ;;move around randomly
set partner one-of (turtles-at -1 0) with [ not partnered? ]
if partner != nobody [ ;;if successful grabbing a partner, partner up
set partnered? true
set heading 270 ;;face partner
ask partner [
set partnered? true
set partner myself
set heading 90
]
]
]
end
;;choose an action based upon the strategy being played
to select-action ;;turtle procedure
if strategy = "random" [ act-randomly ]
if strategy = "cooperate" [ cooperate ]
if strategy = "defect" [ defect ]
if strategy = "tit-for-tat" [ tit-for-tat ]
if strategy = "unforgiving" [ unforgiving ]
if strategy = "unknown" [ unknown ]
add-noise ;;adds noise to the games
end
to play-a-round ;;turtle procedure
get-payoff ;;calculate the payoff for this round
update-history ;;store the results for next time
end
;;calculate the payoff for this round and
;;display a label with that payoff.
to get-payoff
set partner-defected? [defect-now?] of partner
ifelse partner-defected? [
ifelse defect-now? [
set score (score + 1) set label 1
] [
set score (score + 0) set label 0
]
] [
ifelse defect-now? [
set score (score + 5) set label 5
] [
set score (score + 3) set label 3
]
]
end
;;update PARTNER-HISTORY based upon the strategy being played
to update-history
if strategy = "random" [ act-randomly-history-update ]
if strategy = "cooperate" [ cooperate-history-update ]
if strategy = "defect" [ defect-history-update ]
if strategy = "tit-for-tat" [ tit-for-tat-history-update ]
if strategy = "unforgiving" [ unforgiving-history-update ]
if strategy = "unknown" [ unknown-history-update ]
end
;;;;;;;;;;;;;;;;
;;;Strategies;;;
;;;;;;;;;;;;;;;;
;;All the strategies are described in the Info tab.
to act-randomly
set num-random-games num-random-games + 1
ifelse (random-float 1.0 < 0.5) [
set defect-now? false
] [
set defect-now? true
]
end
to act-randomly-history-update
;;uses no history- this is just for similarity with the other strategies
end
to cooperate
set num-cooperate-games num-cooperate-games + 1
set defect-now? false
end
to cooperate-history-update
;;uses no history- this is just for similarity with the other strategies
end
to defect
set num-defect-games num-defect-games + 1
set defect-now? true
end
to defect-history-update
;;uses no history- this is just for similarity with the other strategies
end
to tit-for-tat
set num-tit-for-tat-games num-tit-for-tat-games + 1
set partner-defected? item ([who] of partner) partner-history
ifelse (partner-defected?) [
set defect-now? true
] [
set defect-now? false
]
end
to tit-for-tat-history-update
set partner-history
(replace-item ([who] of partner) partner-history partner-defected?)
end
to unforgiving
set num-unforgiving-games num-unforgiving-games + 1
set partner-defected? item ([who] of partner) partner-history
ifelse (partner-defected?)
[set defect-now? true]
[set defect-now? false]
end
to unforgiving-history-update
if partner-defected? [
set partner-history
(replace-item ([who] of partner) partner-history partner-defected?)
]
end
;;defaults to tit-for-tat
;;can you do better?
;;Generous Tit-for-Tat, cooperates 10% of the time that it would otherwise defect.
to unknown
set num-unknown-games num-unknown-games + 1
set partner-defected? item ([who] of partner) partner-history
ifelse (partner-defected?)
[ifelse (random 100 < 10) ;;be generous in 10% of the cases you would defect
[set defect-now? false]
[set defect-now? true]
]
[set defect-now? false]
end
;;defaults to tit-for-tat-history-update
;;can you do better?
to unknown-history-update
set partner-history
(replace-item ([who] of partner) partner-history partner-defected?)
end
;;;;;;;;;;;
;;;Noise;;;
;;;;;;;;;;;
;;read values from slider and store them
to noise-setup
set noise-active noise ;;Set if noise is active or not depending on switch
set noise-prob-defect prob-def-to-cop ;;Passes the current probability of defect turning into cooperate
set noise-prob-cooperate prob-cop-to-def ;;Passes the current probability of cooperate turning into defect
end
;;changes the decision according to the noise setup
to add-noise
;;check if noise is activated
if (noise-active) [
;;check decision
ifelse (defect-now?)
[
if (random 100 < noise-prob-defect)
[
;;flip defect -> cooperate
set defect-now? false
set noise-defect-true (noise-defect-true + 1) ;;Counter of times a flip has been made
]
]
[
if (random 100 < noise-prob-cooperate)
[
;;flip cooperate -> defect
set defect-now? true
set noise-cooperate-true (noise-cooperate-true + 1) ;;Counter of times a flip has been made
]
]
]
end
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;Plotting Procedures;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;calculate the total scores of each strategy
to do-scoring
set random-score (calc-score "random" num-random)
set cooperate-score (calc-score "cooperate" num-cooperate)
set defect-score (calc-score "defect" num-defect)
set tit-for-tat-score (calc-score "tit-for-tat" num-tit-for-tat)
set unforgiving-score (calc-score "unforgiving" num-unforgiving)
set unknown-score (calc-score "unknown" num-unknown)
end
;; returns the total score for a strategy if any turtles exist that are playing it
to-report calc-score [strategy-type num-with-strategy]
ifelse num-with-strategy > 0 [
report (sum [ score ] of (turtles with [ strategy = strategy-type ]))
] [
report 0
]
endenter code here
Related
I want to make turtles move around and look for a partner (a turtle that is not already partnered that is on the same patch) , and when they found one I want them to hatch a certain number of turtles and then die. But what happens is that when I start the simulation, all turtles die at the first tick. What am I doing wrong?
to go
ask turtles [
partner-up
]
birth
death
tick
end
to partner-up
if (not partnered?) [
rt (random-float 90 - random-float 90) fd 1
set partner one-of (turtles-at 0 0) with [ not partnered? ]
if partner != nobody [
set partnered? true
ask partner [
set partnered? true
set partner myself
]
]
]
end
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
calculate-score
hatch (score + 1)
]
end
to death
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
die
]
end
Two things stand out- one is the call to one-of (turtles-at 0 0) with [ not partnered? ]. This includes ALL turtles on the patch that you indicate (equivalent to turtles-here), which means including the turtle executing the command. I think you want other turtles-here or (other turtles-at 0 0).
Next, your 'baby turtles' are inheriting all the attributes of their parents, including values in their partnered? and partner variables. So, the turtles are being hatched with partnered? = true, and so when the call to death occurs in your go procedure, they qualify as partnered-turtles and therefore die. To correct this, you can explicitly set the variables for your hatched turtles- for example:
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
let score 1
hatch (score + 1) [
set partnered? false
set partner nobody
]
]
end
Also, not sure if this is intentional but wanted to point out that both 'partners' will hatch an offspring. If you want a more standard biological model you may want only one of the parents to hatch.
Revised toy model:
turtles-own [ partnered? partner]
to setup
ca
reset-ticks
ask n-of 10 patches [
sprout 1 [
set partnered? false
set partner nobody
]
]
end
to go
ask turtles [
partner-up
]
birth
death
tick
end
to partner-up
if (not partnered?) [
rt (random-float 90 - random-float 90) fd 1
set partner one-of (other turtles-at 0 0) with [ not partnered? ]
if partner != nobody [
set partnered? true
ask partner [
set partnered? true
set partner myself
]
]
]
end
to birth
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
let score one-of [ 0 1 ]
hatch (score + 1) [
set partnered? false
set partner nobody
]
]
end
to death
let partnered-turtles turtles with [ partnered? ]
ask partnered-turtles [
die
]
end
I am writing a NetLogo model of a housing market and its political ramifications. There are two breeds in the model: households and houses. An early step in my development with which I am having difficulty is having households match to houses via one of two types of links, own or rent, defined by nested conditional statements. This has resulted in two difficulties I haven't been able to overcome as of yet.
Within the command setup-market command, I'm trying to define a set of possible houses to purchase for each household which, if they meet a set of conditions, the household then buys (and creates a link). If it cannot afford to buy, then it will try to rent. If it cannot afford to rent the household will die.
My code continually results in the following error:
IFELSE expected input to be a TRUE/FALSE but got the turtle (house XXX) instead.
There is a further issue I'm having as well later in the code (in the two lines commented out with ";") where I attempt to set the variables owner-occupied and renter to 1 based on the presence of the appropriate link (they should remain 0 and the household should die if it remains unlinked).
The full code is below. The line with ";; This is the line giving me trouble" denotes where the error seems to be occurring.
UPDATE:
Code has been updated with JenB's solution. Resulting error is now:
CREATE-LINK-WITH expected input to be a turtle but got NOBODY instead. which occurs at the line: create-link-with one-of potentialHomes [ set color red
undirected-link-breed [own-links own-link]
undirected-link-breed [rent-links rent-link]
breed [city-centers city-center]
breed [households household]
households-own
[
age
money
income
monthly-income
consumption
monthly-consumption
hh-size race
preference
net-income
net-monthly-income
myHouse
]
breed [houses house]
houses-own
[
cost
down-payment
mortgage-payment
rent
rent-premium
rooms
onMarket
owner-occupied
rental
onMarket?
]
patches-own [
seed? ;;district seed
district ;;district number
full? ;;is the district at capacity?
quadrant
]
to setup
clear-all
reset-ticks
setup-patches
set-default-shape households "person"
create-households num-households [ setxy random-xcor random-ycor ]
set-default-shape houses "house"
create-houses num-houses [ setxy random-xcor random-ycor ]
setup-households
setup-houses
setup-market
generate-cities
end
to generate-cities
let center-x random-xcor / 1.5 ;;keep cities away from edges
let center-y random-ycor / 1.5
end
to setup-patches
ask patches with [pxcor > 0 and pycor > 0] [set quadrant 1 set pcolor 19 ]
ask patches with [pxcor > 0 and pycor < 0] [set quadrant 2 set pcolor 49 ]
ask patches with [pxcor < 0 and pycor < 0] [set quadrant 3 set pcolor 139 ]
ask patches with [pxcor < 0 and pycor > 0] [set quadrant 4 set pcolor 89 ]
end
to setup-households
ask households
[ set age random-poisson 38
set money random-exponential 30600
set income random-exponential 64324
set monthly-income income / 12
set consumption .5 * income
set monthly-consumption consumption / 12
set hh-size random 6 + 1
set net-income income - consumption
set net-monthly-income monthly-income - monthly-consumption
]
end
to setup-houses
ask houses
[ set cost random-normal 300000 50000
set down-payment cost * down-payment-rate
set mortgage-payment (cost - down-payment) / 360
set rooms random-exponential 3
set onMarket 1
set rent mortgage-payment + mortgage-payment * .25
set owner-occupied 0
set rental 0
]
end
to setup-market
ask houses
[ set onMarket? TRUE ]
ask households
[ ifelse any? houses with [ [money] of myself > down-payment and [net-monthly-income] of myself > mortgage-payment ]
[ let potentialHomes houses with [[money] of myself > cost and onMarket? ]
create-link-with one-of potentialHomes [
set color red
]
]
[
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [ [net-monthly-income] of myself > rent and onMarket? ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
]
]
ask houses
[ if any? link-neighbors [set onMarket FALSE ]
;if any? link-neighbors and color red [ set owner-occupied 1 ]
;if any? link-neighbors and color blue [ set rental 1 ]
]
end
to go
move-households
tick
end
to move-households
ask households [
move-to myHouse
]
end
You don't need to "suspect" where the problem is, NetLogo points to the problem line. Running your code, the problem is actually ifelse one-of houses with [ [net-monthly-income] of myself > rent]. Looking at that line, you pull out a randomly selected house from the pool with rent less than income. But you don't have a condition for the ifelse to test.
In previous constructions you have had != nobody at the end but you forgot that in this line. That will fix the error, but your code would be much less error prone if you used any? instead. You seem to be using one-of .... != nobody to test whether there are any turtles that satisfy the condition. That's what any? is for.
So instead of:
ifelse one-of houses with [ [net-monthly-income] of myself > rent] != nobody
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
you can have:
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
I should add that there is a potential logic problem here. Say there are houses with rent lower than income, the code goes to the first (true) actions. But there's no guarantee that there are any houses that satisfy the new conditions, which are different.
Also, NetLogo has the concept of true and false so you don't need to use 1 and 0. By convention (but not required), boolean variable names end with a question mark. So you could have set onMarket? true instead of set onMarket 1. Why would you do this? It makes logical operators cleaner and easier to read (which reduces bugs). Your line:
let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
would look like:
let potentialRentals houses with [[money] of myself > rent and onMarket? ]
And you can do things like if not onMarket? instead of if onMarket? = false or if onMarket = 0
Im very new to Netlogo and trying to learn the basic. Therefore, I'm trying to extend an example code Netlogo provided. Im trying to make the pollution rate dependent upon the number of people from the Urban Site Pollution example.
Is there also a way to introduce reinforced learning (Q-learning) to improve the simulation?
Sincerly,
Victor
Do I need to create a new function that updates pollution when population increased?
Below is the example code:
breed [ people person ]
breed [ trees tree ]
turtles-own [ health ]
patches-own [
pollution
is-power-plant?
]
to setup
clear-all
set-default-shape people "person"
set-default-shape trees "tree"
ask patches [
set pollution 0
set is-power-plant? false
]
create-power-plants
ask patches [ pollute ]
create-people initial-population [
set color black
setxy random-pxcor random-pycor
set health 5
]
reset-ticks
end
to go
if not any? people [ stop ]
ask people [
wander
reproduce
maybe-plant
eat-pollution
maybe-die
]
diffuse pollution 0.8
ask patches [ pollute ]
ask trees [
cleanup
maybe-die
]
tick
end
to create-power-plants
ask n-of power-plants patches [
set is-power-plant? true
]
end
to pollute ;; patch procedure
if is-power-plant? [
set pcolor red
set pollution polluting-rate
]
set pcolor scale-color red (pollution - .1) 5 0
end
to cleanup ;; tree procedure
set pcolor green + 3
set pollution max (list 0 (pollution - 1))
ask neighbors [
set pollution max (list 0 (pollution - .5))
]
set health health - 0.1
end
to wander ;; person procedure
rt random-float 50
lt random-float 50
fd 1
set health health - 0.1
end
to reproduce ;; person procedure
if health > 4 and random-float 1 < birth-rate [
hatch-people 1 [
set health 5
]
]
end
to maybe-plant ;; person procedure
if random-float 1 < planting-rate [
hatch-trees 1 [
set health 5
set color green
]
]
end
to eat-pollution ;; person procedure
if pollution > 0.5 [
set health (health - (pollution / 10))
]
end
to maybe-die ;; die if you run out of health
if health <= 0 [ die ]
end
; Copyright 2007 Uri Wilensky.
; See Info tab for full copyright and license.
Good morning people,
At the moment I have a template in netlogo that allows to visualize routes of deliveries in houses created randomly.
globals[route-vector]
breed [carr car]
breed [spare spares]
breed [hous housess]
breed [spawns spawn]
carr-own [ route route-counter spawn-target target route-complete?]
spare-own[ route route-counter spawn-target target route-complete?]
to setup
clear-all
create-carros
create-casas
path
reset-ticks
end
to create-carros
create-carr 2 [ set color green ]
ask carr [
set size 1.5
setxy random-xcor random-ycor
set route-counter 0
set target nobody
set route []
set route-complete? false
pd
]
end
to create-carspare
create-spare 1 [ set color blue ]
ask spare [
set size 1.5
setxy random-xcor random-ycor
set route-counter 0
set target nobody
set route []
set route-complete? false
pd
]
end
to create-casas
create-hous 5 [ set color red ]
ask hous [
set shape "house"
set size 1.5
setxy random-xcor random-ycor
]
end
to path
set route-vector [4 7 6 3 5 0 1 1 0 1]
let houses sublist route-vector 0 (length route-vector / 2 )
let carlist sublist route-vector (length route-vector / 2 ) (length route-
vector)
(foreach carlist houses
[ [the-car the-house] ->
ask car the-car [
set route lput ( housess the-house ) route
]
]
)
ask carr [
hatch 1 [
set breed spawns
ht
]
set spawn-target one-of other turtles-here with [
xcor = [xcor] of myself
]
]
end
to go
ask carr with [ not route-complete? ] [
if route = [] [
set target spawn-target
]
if target = nobody [
set target item route-counter route
]
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
ifelse target != spawn-target [
set route-counter route-counter + 1
] [
set route-complete? true
]
set target nobody
]
if route-counter > length route - 1 [
set route-counter 0
set target spawn-target
]
]
tick
end
I thought about using a broken or crash switch, and a slider with how many maximum home deliveries per car.
in my go procedure I put:
ask carr with [failure?] [
if ticks = 25 [ask one-of carr [set crash? TRUE]
set target spawn-target
Assuming the maximum deliveries per car are 3 and as one or more houses will not be visited because of the car that stopped, I put a reschedule button:
to reschedule
ask one-of spare with [not route-complete?] ; How do I make the reservation
car take the route of the car that stopped?
[
set target [car route that stopped]
]
set target spawn-target
end
I need some help in my reschedule bottom. if a car stops, and does not finish the route, the reserve car should take over the houses that are missing to visit
Thanks in advance for your understanding, and if you can help, I was grateful.
If I understand what you are asking, you have a car that has crashed and want to pass on the content of one of its variables to the spare car. The car that is crashed has the variable crash? set to TRUE, but I can't see from your code how you define a car to be the spare car. But it's probably something like this.
ask cars
[ <doing whatever they do>
if <conditions for crash>
[ set crash? TRUE
ask one-of cars with [spare?]
[ set spare? FALSE
set target [target] of myself
]
stop
]
]
I'm trying to set a resource variable. It will be time and will function like sugar in sugarscape. Its setup is: ask agentes [set time random-in-range 1 6].
The thing is... I want the agentesto participate in activities linking like we said here. But, with each participation, it should subtract a unity of agentes's time. I imagine it must be with foreachbut I seem to be unable to grasp how this works.
ask n-of n-to-link agentes with [n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
while [time >= 2] [
create-participation-with myself [ set color [color] of myself ] ]
foreach (command I don't know)[
set time time - count participations]]
Essentially, I want the agentes to look if they have time to participate. If they do, they create the link and subtract 1 to their time. Only ONE per participation. If they have 3 time, they'll have 2 participations and 1 time. If they have 1 time, they won't have links at all.
EDIT
You're right. I don't need while. About foreach, every place I looked said the same thing but I can't think of other way. About colors, they're only for show purpose.
The relationship between time and participation counts is as follows: the agentes have time they can spend in activities. They participate if time>=2. But every participation (link with activity) consumes 1 time when the link is active (I didn't write the decay code yet; they'll regain their time when it is off).
EDIT V2
Nothing, it keeps subtracting even with the []. Maybe the best choice is if I give you the code so you can try it. You'll have to set 5 sliders: prob-female (53%), initial-people (around 200), num-activity (around 20), n-capacity (around 25) and sight-radius (around 7). And two buttons, setup and go. I also set a patch size of 10 with 30 max-pxcor and max-pycor. Here is the code. Sorry if I'm not clear enough!
undirected-link-breed [participations participation]
turtles-own [
n-t-activity
]
breed [activities activity]
activities-own [
t-culture-tags
shared-culture
]
breed [agentes agente]
agentes-own [
gender
time
culture-tags
shared-culture
]
to setup
clear-all
setup-world
setup-people-quotes
setup-activities
reset-ticks
END
to setup-world
ask patches [set pcolor white]
END
to setup-people-quotes
let quote (prob-female / 100 * initial-people)
create-agentes initial-people
[ while [any? other turtles-here ]
[ setxy random-xcor random-ycor ]
set gender "male" set color black
]
ask n-of quote agentes
[ set gender "female" set color blue
]
ask agentes [
set culture-tags n-values 11 [random 2]
set shared-culture (filter [ i -> i = 0 ] culture-tags)
]
ask agentes [
set time random-in-range 1 6
]
ask agentes [
assign-n-t-activity
]
END
to setup-activities
create-activities num-activity [
set shape "box"
set size 2
set xcor random-xcor
set ycor random-ycor
ask activities [
set t-culture-tags n-values 11 [random 2]
set shared-culture (filter [i -> i = 0] t-culture-tags)
]
ask activities [
assign-n-t-activity]
]
END
to assign-n-t-activity
if length shared-culture <= 4 [
set n-t-activity ["red"]
set color red
]
if length shared-culture = 5 [
set n-t-activity ["green"]
set color green
]
if length shared-culture = 6 [
set n-t-activity ["green"]
set color green
]
if length shared-culture >= 7 [
set n-t-activity ["black"]
set color black
]
END
to go
move-agentes
participate
tick
end
to move-agentes
ask agentes [
if time >= 2 [
rt random 40
lt random 40
fd 0.3
]
]
end
to participate
ask activities [
if count my-links < n-capacity [
let n-to-link ( n-capacity - count my-links)
let n-agentes-in-radius count (
agentes with [
n-t-activity = [n-t-activity] of myself ] in-radius sight-radius)
if n-agentes-in-radius < n-to-link [
set n-to-link n-agentes-in-radius
]
ask n-of n-to-link agentes with [
n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
if time >= 2 [
create-participation-with myself [
set color [color] of myself ]
ask agentes [set time time - count my-participations] ]
]
ask activities [
if not any? agentes in-radius sight-radius [
ask participations [die]
]
]
]
]
end
to-report random-in-range [low high]
report low + random (high - low + 1)
END
EDIT V3
I asked Bill Rand to help me and he solved the problem. The issue was in this line: let candidates agentes with [ n-t-activity = [n-t-activity] of myself ] in-radius sight-radius. He solved the problem this way: let candidates agentes with [ n-t-activity = [n-t-activity] of myself and not participation-neighbor? myself ] in-radius sight-radius. Being this and not participation-neighbor? myself the condition to make sure that the agente is not already a part of that activity.
You almost never need foreach in NetLogo. If you find yourself thinking you need foreach, your immediate reaction should be that you need ask. In particular, if you are iterating through a group of agents, this is what ask does and you should only be using foreach when you need to iterate through a list (and that list should be something other than agents). Looking at your code, you probably don't want the while loop either.
UPDATED FOR COMMENTS and code - you definitely do not need while or foreach.
Your problem is the following code. You ask agentes that satisfy your conditions to create the links, but then you ask ALL AGENTES to change their time (line I have marked), not just the agentes that are creating participation links.
ask n-of n-to-link agentes with [
n-t-activity = [n-t-activity] of myself] in-radius sight-radius [
if time >= 2 [
create-participation-with myself [
set color [color] of myself ]
ask agentes [set time time - count my-participations] ] ; THIS LINE
]
The following code fixes this problem. I have also done something else to simplify reading and also make the code more efficient - I created an agentset (called candidates) of the agentes that satisfy the conditions. In this code, the candidates set is only created once (for each activity) instead of twice (for each activity) because you are creating it to count it and then creating it again to use for participation link generation.
to participate
ask activities
[ if count my-links < n-capacity
[ let candidates agentes with [
n-t-activity = [n-t-activity] of myself ] in-radius sight-radius
let n-to-link min (list (n-capacity - count my-links) (count candidates ) )
ask n-of n-to-link candidates
[ if time >= 2
[ create-participation-with myself [ set color [color] of myself ]
set time time - count my-participations ] ; REPLACED WITH THIS LINE
]
ask activities [
if not any? agentes in-radius sight-radius [
ask participations [die]
]
]
]
]
end