NetLogo: Moving percent of turtles - netlogo

I created 1000 turtles in NetLogo which move randomly, but I want only thirty percent of them to move forward one step and the other seventy percent to move forward five steps.
to setup
ca
setup-turtles
setup-patches
reset-ticks
end
to go
move-turtles
tick
end
to setup-patches
ask patches [set pcolor brown]
end
to setup-turtles
create-turtles number
ask turtles [set shape "person" set size 1]
ask turtles [setxy random-xcor random-ycor] ;; posicionar las personas en un punto al azar
end
to move-turtles
ask turtles [
right random 360]
end

One simple and fast way to approach this would be to do it probabilistically:
ask turtles [ fd ifelse-value (random 100 <= 30) [ 1 ] [ 5 ] ]
...so that each turtle would move one step with a probability of 30% and five steps with a probability of 70%. But it wouldn't guarantee that exactly 30% of your turtles move one step. It would just average to 30% in the long run.
If you want exact numbers, one way to do it would be:
let small-movers n-of (count turtles * 0.3) turtles
let big-movers turtles with [ not member? self small-movers ]
ask small-movers [ fd 1 ]
ask big-movers [ fd 5 ]
But this will be slowish because of the member? check.
A much faster way would be to use a turtle variable. Assuming you have:
turtles-own [ step-size ]
Then you can do:
ask turtles [ set step-size 5 ]
ask n-of (count turtles * 0.3) turtles [ set step-size 1 ]
ask turtles [ fd step-size ]

Related

How do you fix a problem with convert probability on a zombie apocalypse simulation on Netlogo [duplicate]

This question already has an answer here:
How do you go about making a convert probability chance for an agent in netlogo?
(1 answer)
Closed 1 year ago.
currently I'm working on a zombie apocalypse simulation on Netlogo, and I'm almost done except that the convertion function is not working. when the zombies collide with humans the humans they either die or convert the human to a zombie according to the global variable convert_probability. For example, if convert probability is set to 80 the human would have an 80% chance of winning the fight and killing the zombie and the zombie would have a 20% chance of converting the human to a zombie.
Also, zombies and humans are not allowed to pass over the brown patches and the function I wrote for that is change_direction, but had to comment those parts because I run to an error.
I have spent hours but couldnt come up with a solution so I would really appreciate any help;
breed [humans human]
humans-own [ humans_speed]
turtles-own [
infected?
]
patches-own [
block
]
breed [zombies zombie]
zombies-own [ zombies_speed]
globals [
student_id
username
nzomb
%infected
]
to setup_world
clear-all
reset-ticks
set student_id 19009670
ask patches [set pcolor green]
set-default-shape zombies "person"
set-default-shape humans "person"
create-zombies 5 [
set color red
set size 4
set zombies_speed 0.5
setxy random-pxcor random-pycor
]
ask zombies[
move-to one-of patches with [pcolor = green]
]
create-humans 15 [
set color blue
set size 4
set humans_speed 1 + random-float 0.1
setxy random-pxcor random-pycor
]
ask humans[
move-to one-of patches with [pcolor = green]
]
set %infected (count turtles with [color = red ] / 20 ) * 100
set nzomb 0
draw_blocks
end
to draw_blocks
ask patches [
set block false
]
ask n-of 100 patches with [pcolor = green][
set pcolor brown
set block true
]
end
to change_direction
if[block] of patch-ahead 2 = true [
right 180
face one-of patches in-radius 2 with [not block]
]
end
to run_model
if ticks >= 10000 [ stop ]
tick
move-turtles
convert
if not any? humans [stop]
end
to move-turtles
ask humans [move-humans]
ask zombies [move-zombies]
end
to move-humans
ask humans [
if any? zombies in-radius (10 + random 20) [rt 180]
set infected? false
set heading (heading + 45 - (random 90))
forward 1 + random-float 1.1
zombiedeath
convert
;;change_direction
]
end
to move-zombies
ask zombies [
chasehuman
convert
zombiedeath
set %infected (count turtles with [color = red ] / 20 ) * 100
set infected? true
set heading (heading + 45 - (random 90))
forward 0.5
; change-direction
]
end
to chasehuman
if any? humans in-radius 10 [
set heading towards one-of humans in-radius 10]
; change_direction
end
to runaway
face min-one-of zombies [distance myself]
rt 180
;change_direction
end
to convert
ask turtles with [ breed = zombies ]
[
ask humans-on patch-here
[
if random 100 < convert_probability [set breed zombies]]
ask humans-on patch-here [if random 100 < convert_probability
[set color red]]
]
end
to zombiedeath
ask zombies-on patch-here [if random 100 > convert_probability
[die]]
end
Okay, the only procedure relevant to this question is this one (same code as above, formatted so you can see the structure logic}:
to convert
ask turtles with [ breed = zombies ]
[ ask humans-on patch-here
[ if random 100 < convert_probability
[ set breed zombies
]
]
ask humans-on patch-here
[ if random 100 < convert_probability
[ set color red
]
]
]
end
You haven't actually told us what the problem is - "convertion function is not working" does not say whether it is generating an error, or what behaviour it is doing compared to what is expected for example. But, look at what this code actually does. First it finds all the zombies then, for each zombie, it:
gets the humans on the same patch to convert to zombies with some probability
gets the humans on the same patch to change colour to red with some probability
Your first problem is that you haven't linked the turning red with becoming a zombie. Is that the problem you were trying to solve? If so, here is some cleaned up code that links zombie and red:
to convert
ask zombies ; note, you can just directly use the breed name
[ ask humans-here ; again, can use the breed name
[ if random 100 < convert_probability
[ set breed zombies
set color red
]
]
]
end

Change the color of the patch based on income level

Hi, this is a continuation of my previous question. Basically I'm
trying to differentiate the patches by its income level and once I
have established this I will set a monitor to count them. However,
when I run the model the patches are not updating. Where am I going
wrong? Appreciate your assistance.
turtles-own [wealth]
patches-own [income]
to setup
ca
setup-turtles
setup-patches
reset-ticks
end
to setup-turtles
create-turtles num-turtles
ask turtles
[
set shape "person"
set size 1
setxy random-xcor random-ycor
set wealth 100
]
end
to setup-patches
ask n-of 2000 patches [ set pcolor green ] ;; to identify patches that will accumulate income from turtles
end
to go
if not any? turtles with [wealth > 0] [stop]
move-turtles
spend
tick
end
to move-turtles ;; turtles to stop once they are spend all their wealth
ask turtles [
ifelse wealth > 0
[rt random 360 forward 1]
[stop]
]
end
to color-patches ;; patch colors to change based on their income level
ask patches [
ifelse income > 0 and income < 100 [
set pcolor 15
] [
ifelse income > 100 and income < 200 [
set pcolor 45
] [
ifelse income > 200 [
set pcolor 64
] [
set pcolor green
]
]
]
]
end
to spend
ask turtles with [wealth > 0] [
if pcolor = green [
set wealth wealth - 1
set income income + 1
]
]
end
The short answer is that you created the procedure to update patch colours but you never told NetLogo to run it. You probably want to add a line to your go procedure, I think this order:
to go
if not any? turtles with [wealth > 0] [stop]
move-turtles
spend
color-patches ; this is what you are missing
tick
end
This is not relevant to your question, but I also noticed that you have this code for moving:
to move-turtles ;; turtles to stop once they are spend all their wealth
ask turtles [
ifelse wealth > 0
[rt random 360 forward 1]
[stop]
]
end
You don't need to ask every turtle and then use stop to exit for some of them, instead it is generally easier to filter the turtles using with. So that code could be replaced with:
to move-turtles
ask turtles with [wealth > 0] [
rt random 360
forward 1
]
end

Is there a possibility to have an ifelse statement with two conditions (ticks mod and probability)?

I'm fairly new to Netlogo but I want to build a model where an agent (a car driver) will leave his home at a certain hour with a certain probability. Let's say he leaves Monday morning at 1 am (if have linked the ticks to the time so one tick is one hour).
I tried to work with ifelse-statements combined with a second statement which has to be verified in order for the entire statement to become true. In the example below the car / agent should leave with a probability of 7.7% its house and drive to a patch called underway-patches. Since one week has 168 hours, I tried to link the hour via the mod ticks (hence, mod ticks = 1 is equal to 1 am on a Monday morning).
This alone works:
ifelse ticks mod 168 = 1 and random-float 100.0 < 7.7
[ ask turtles [ move-to one-of underway-patches ] ]
[ ask turtles [ move-to one-of home-patches] ]
This works fine. So I have always about 7 out of 100 turtles moving to the underway-patch.
But If I now add the second hour, so 2 am, the first function does not work anymore (there are no turtles moving at all at 1 am - only at 2 am). I expect about 7 out of 100 turtles to move at 1 am to the underway-patch and then I expect about 5 out of 100 turtles to move at 2 am to the underway-patch (and the other 7 of the first hour should go back to the home-patches).
This does not work anymore:
; Monday, 1 am
ifelse ticks mod 168 = 1 and random-float 100.0 < 7.7
[ ask turtles [ move-to one-of underway-patches ] ]
[ ask turtles [ move-to one-of home-patches] ]
; Monday, 2 am
ifelse ticks mod 168 = 2 and random-float 100.0 < 5.1
[ ask turtles [ move-to one-of underway-patches] ]
[ ask turtles [move-to one-of home-patches] ]
I appreciate every help! Thanks in advance.
First, congratulations on an extremely clear question despite your newness to the site.
The problem is not that you have multiple ifelse statements, that is fine. The issue is that your ifelse statement is applying a single test to all turtles. Just look at the first example with one statement:
ifelse ticks mod 168 = 1 and random-float 100.0 < 7.7
[ ask turtles [ move-to one-of underway-patches ] ]
[ ask turtles [ move-to one-of home-patches] ]
Imagine that it is tick number 1. The computer runs the random number generator and gets 2. Great, the condition is true so the first block gets run. That will have ALL turtles move to the underway-patches. Similarly, if the random number generator returns 10, then the condition is false and ALL turtles move to home-patches.
You probably want something more like (you don't have to do the brackets on multiple lines, I did it so you can see the logical blocks of the structure):
ifelse ticks mod 168 = 1
[ ask turtles-on home-patches
[ if random-float 100.0 < 7.7
[ move-to one-of underway-patches
]
]
]
[ ask turtles-on underway-patches [ move-to one-of home-patches] ]
Or if you want exactly the correct proportion of turtles to move:
ifelse ticks mod 168 = 1
[ let num-to-move 0.077 * count turtles-on home-patches
ask n-of num-to-move turtles-on home-patches
[ move-to one-of underway-patches
]
]
[ ask turtles-on underway-patches [ move-to one-of home-patches] ]
Just a general observation, if you are going to code this for every possible starting time, you are going to have a lot of code that is identical except for the tick and the proportion. You state that you are new to NetLogo, so I don't want to jump too quickly to more advanced concepts, but come back when you're a little further along with having thought through your model and we can probably help you create a procedure that reduces the need to duplicate code.
UPDATE: One approach to reusing the code
This isn't quite right because I'm not really clear what sort of movement you want, but here is a complete model where the proportions are stored in a list and ticks is used to identify the correct item in the list. That proportion is then passed to a piece of code that moves turtles.
globals
[ home-patches
underway-patches
proportions
]
to setup
clear-all
set proportions [0 0.077 0.05 0.15]
set home-patches patches with [abs pxcor <= 3 and abs pycor <= 3]
ask home-patches [ set pcolor white ]
set underway-patches patches with [not member? self home-patches]
ask underway-patches [ set pcolor yellow ]
create-turtles 100
[ set color red
]
reset-ticks
end
to go
move-turtles item (1 + ticks mod 3) proportions
tick
end
to move-turtles [#prop]
print #prop
ask turtles
[ ifelse member? patch-here home-patches
[ if random-float 1 < #prop
[ move-to one-of underway-patches
]
]
[ move-to one-of home-patches
]
]
end

Netlogo increase turtle number by tick

I am trying to build a model where turtle move one patch per tick with random movement. I am looking for a solution to increase the number of turtle per tick based on the percentage. For ex. In the beginning there are 7 turtles, by each tick they should increase by following percentage:
10.72%
10.83%
10.93%
11.03%
11.11%
11.19%
11.27%
11.33%
11.39%
11.45%
Not sure if this is possible? If needed this can be round up to whole number.
If this is not possible, how can I increase the turtle number by 11% each tick for 10 ticks then after 12% each tick for another 10 ticks and so on?
Below is the code that I am using.
to setup
clear-all
setup-turtles
setup-patches
reset-ticks
end
to setup-patches
ask patches [ set pcolor green ]
end
to setup-turtles
create-turtles tourists [setxy random-xcor random-ycor ]
ask turtles [ set shape "person" set size 2 ]
end
to go
if ticks >= 130 [ stop ]
move-turtles
eat
tick
end
to move-turtles
ask turtles [ right random 360 forward 1]
end
to eat
ask turtles [ if pcolor = green [ set pcolor black ] ]
end
Thank you for your support.
Avi
I think your model is very similar to 'Rabbits Grass Weeds' in the Models Library so you might want to have a look at that to get some ideas. Focusing just on the revised question of moving to a green patch, you need with, which will restrict choices. Note that the code below will break if there are no neighbouring patches that are green.
to setup
clear-all
setup-turtles
setup-patches
reset-ticks
end
to setup-patches
ask patches [ set pcolor green ]
end
to setup-turtles
create-turtles 7 [setxy random-xcor random-ycor ]
ask turtles [ set shape "person" set size 2 ]
end
to go
if ticks >= 130 [ stop ]
move-turtles
increase-turtles
tick
end
to move-turtles
ask turtles [ move-to one-of neighbors with [pcolor = green] ]
end
to increase-turtles
ask one-of turtles [ hatch 1 ]
end
I used hatch in this code, which gets one turtle to create another turtle at the same place with the same colour etc. If you want to just create a new turtle in exactly the same way as your original turtles, then you want something more like this.
to setup
clear-all
make-turtles 7
setup-patches
reset-ticks
end
to setup-patches
ask patches [ set pcolor green ]
end
to make-turtles [ num ]
create-turtles num
[ setxy random-xcor random-ycor
set shape "person"
set size 2
]
end
to go
if ticks >= 130 [ stop ]
move-turtles
increase-turtles
tick
end
to move-turtles
ask turtles [ move-to one-of neighbors with [pcolor = green] ]
end
to increase-turtles
make-turtles 1
end
In this case, I have made a new procedure (called make-turtles) that creates as many turtles as you specify, randomly locates them etc. In setup, I call it to make 7 turtles, and then later on just make 1 each time.

Define home area-turtles?

I am very new to netlogo. I have searched every question here before I posted this.
I have the following code which sprouts a given number of horses:
ask n-of Number-horses patches with [grass? = "Yes"]
[sprout-horses 1 [set color 25 ]]
The person can change the number of horses using the slider but I would like each horse to have its own area/range/radius.
They can only move within this radius/area and they cannot meet each other.
From what I've read it's got something to do with the distance function?
You can find a similar problem here which has examples too :
Spacing agents in NetLogo based on territory size
There are several ways that you can assign a territory zone to each horse, but all methods that I know have two steps, first step is in order to make sure initial home area of horses are separated from each other , So we need to create horses only in patches which has a certain distance from another patch which has a horse on it,I did not follow your method that asked patches to sprout horses and instead I created them without asking patches.
I was not sure how you defined grass? Variable for each patch but I have assigned a number of patches with grass? = true and others false.
Second step is to set home-area property of each horse. If initially you moved them far away from each other they will have separate territories.
I have included a few examples here :
First to use in-radius for both steps:
Breed [Horses horse]
Horses-own [home-area]
patches-own [grass?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask patches
[
ifelse pxcor mod 5 = 3
[ set Grass? true ]
[ set Grass? false ]
]
create-horses Number-horses
[ Move-to one-of patches with [Grass? and not any? other horses in-radius (Zone-Radius + 1)]
set home-area patches in-radius Zone-Radius
set color 25
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area
[rt random 10 fd 1 ] ; move if next patch is in their zone
[rt random 180]
]
tick
end
In this example horses only move in the patches in their radius 2. But you can change that base on your model requirements.
In the second method you can use distance for the first step (finding empty patches with enough distance to current patch) and radius for second one (assigning home-area to each horse).
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches in-radius Zone-Radius
If you use higher distance for finding empty patches you will have completely seprated zones. Finally , you can use distance for both steps:
Move-to one-of patches with [Grass? and not any? other horses with [distance myself < (Zone-Radius + 1)]]
set home-area patches with [distance myself < Zone-Radius]
I just did it another way:
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
let i 0
while [i < Number-horses]
[
ask one-of patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
set i (i + 1)
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end
As you can see I used while and a condition to ask patches one by one, I might be mistaken but when I ask all the n-of Number-of-horses patches with [YourCondition][...] I get the wrong results and distance between horses is not effective, maybe they are created all at the same time and therefore upon creating a horse there was no horse nearby!? I am new to these concepts and might be wrong.
This is the code and view for the one which asks patches to create horses at once here :
Breed [Horses horse]
Horses-own [home-area]
patches-own [ concession? forest? parks?]
globals [Zone-Radius]
to setup
clear-all
reset-ticks
set Zone-Radius 2
ask n-of 500 patches [ set concession? "No" ]
ask n-of 500 patches[ set forest? "Yes" ]
ask n-of 500 patches[ set parks? "Yes"]
ask n-of number-horses patches with [(concession? = "No" or forest? = "YES" or parks? = "YES" ) and (not any? horses in-radius (Zone-Radius + 2) )]
[
sprout-horses 1 [
set home-area patches with [distance myself < Zone-Radius]
let w who
ask home-area [set pcolor red]
set color 25 ]
]
end
to go
ask horses [
ifelse member? patch-ahead 1 home-area [rt random 10 fd 1 ] [rt random 180]
]
tick
end