How to calculate turtles within a certain distance in Netlogo - netlogo

I want to calculate the number of shops within a certain distance of the turtle location. I tried both methods that I write below and I get the same radius. I want to increase the radius to include more than the neighbour patches but changing the value in-radius from 3 to 500 doesn't make a difference in the model. Is there a different way to calculate the shops, let's say within 5 patches from where the turtle is located?
turtles-own [ healthy-exposure
unhealthy-exposure ]
to setup
ca
ask households [ setxy random-xcor random-ycor
set size 0.9
set shape "person"
set color grey ]
ask healthy-shops [ setxy random-xcor random-ycor
set shape "house"
set size 0.6
set color 52 ]
ask unhealthy-shops [ setxy random-xcor random-ycor
set shape "house"
set size 0.6
set color 15 ]
calculate-exposure1 or calculate-exposure2 ;; choose one or the other
end
to calculate-exposure1
ask household 1 [ set healthy-exposure count healthy-shops in-radius 3
set pcolor 15
set unhealthy-exposure sum [unhealthy-shops] of neighbors ]
end
to calculate-exposure2
ask household 1 [ set healthy-exposure count healthy-shops with [ distance myself < 500]
set pcolor 15
set unhealthy-exposure sum [unhealthy-shops] of neighbors ]
end

Related

How to give property to agents Netlogo

I´m setting up some turtles randomly on the the map, then they have to change the color of the patches to show that they cultivated however some times they overlap and change the color of other turtles. To solve this i asked not any? other turtles in-radius 6 to force them to be apart, but this is not elegant nor efficient. What would be a better way to give each turtle their own patch to make a more populated world.
to setup
ca
resize-world 0 100 0 100
create-turtles 50
[ set size 1
set color 135
setxy random-xcor random-ycor
move-to one-of patches with [not any? other turtles in-radius 6]
ask patches in-radius (2 + random 2) [set pcolor 35]
]
end
to go
ask turtles[ ask patches in-radius 4 with [pcolor = 35]; falta representar las cosechas 4-2-3-3
[ set pcolor 42]]
end
The go is using the fact that there are no turtles in a radius of 6, but if i wanted to get them closer or change the color on different ticks this would be bad.
Thanks. If more is need please let me know.
You can give the turtles a new turtles-variable that you can assign a patch-set to. This is done by using turtles-own at the start of your program.
The turtle then remembers which patches were assigned to this variable and can access them again at a later time. This way, when it comes time to change patch colors, they only change the colors of patches within their original radius and not of the patches in the extended radius.
turtles-own [territory]
to setup
ca
resize-world 0 100 0 100
create-turtles 50
[ set size 1
set color 135
setxy random-xcor random-ycor
set territory patches in-radius (2 + random 2)
ask territory [set pcolor 35]
]
end
to go
ask turtles [ ask territory ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]]
end
As an alternative solution, here it is not the turtles that remember which patch they own, but the patches that remember which turtle owns them. In the case I use here, patches can only be owned by a single turtle.
Here, I give each patch a patch-variable using patches-own. I then let the turtles tell the patches within their radius to choose that turtle as their owner ask patches ... [set owner myself]. Myself is a reporter that refers not to the patch carrying out the command, but to the turtle that asked the patch to carry out the command.
patches-own [owner]
to setup
ca
resize-world 0 100 0 100
create-turtles 50 [
set size 1
set color 135
setxy random-xcor random-ycor
ask patches in-radius (2 + random 2) [
set owner myself
set pcolor 35
]
]
end
to go
ask turtles [ ask patches in-radius 4 with [owner = myself] ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]
]
end
If multiple turtles try to be the owner of the same patch, the last one becomes the owner. This is because each turtle completely overwrites the previous owner value.
If you still want an option for multiple owners, you can work with a turtle-set instead. This requires a few different primitives.
In setup, you have to define owners as an empty turtle-set in order for the rest to work, using set owners (turtle-set).
To then assign a turtle to owners, you use set owners (turtle-set owners myself). This changes the owners turtle-set to add the turtle calling the patch to the set.
Finally, you can no longer ask patches to with [owner = myself] to change color since owners is now a turtle-set, not a turtle. Instead, you use the member? primitive that looks if a turtle is part of a turtle-set.
patches-own [owners]
to setup
ca
resize-world 0 100 0 100
ask patches [set owners (turtle-set)]
create-turtles 50 [
set size 1
set color 135
setxy random-xcor random-ycor
ask patches in-radius (2 + random 2) [
set owners (turtle-set owners myself)
set pcolor 35
]
]
end
to go
ask turtles [
ask patches in-radius 4 with [member? myself owners] ; falta representar las cosechas 4-2-3-3
[ set pcolor 42]
]
end

Create a gradient for a turtle swarm

I created a rectangular turtle grid using a total of 1000 turtles.
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape [ sprout 1 ]
Now I need to create a sort of gradient, that will give a sense of distance to my turtle swarm. Given a "seed" with value 0, it emits a message with its value 0 in a certain talk_radius.
The turtles inside this talk_radius compute their distance to the seed. If the distance is less than a fixed value (called gradient_distance) the turtle will assume 1 as gradient_value, emitting a message with its value.
The other turtles do the same. So everyone will take the value x + 1, where x is the lowest value of the turtle within the gradient_distance, as shown in the picture
This is the relative algorithm in pseudo code:
loop
if gradient seed = TRUE then // check if robot is designated as gradient source
gradient value(self) = 0
else
gradient value(self) = GRADIENT MAX
for all neighbors n do
if measured distance(n) < G then // G represents the gradient-distance and GRADIENT MAX is infinity
if gradient value(n) < gradient value(self) then
gradient value(self) = gradient value(n)
gradient value(self) = gradient value(self) + 1
transmit gradient value(self)
And that's my implementation in netlogo:
globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed gradient_value]
to setup
ca
resize-world -60 60 -20 20
crt 1000
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape [ sprout 1 ]
set talk_radius 4
set gradient_max 100000
set gradient_distance 1
ask turtles
[set shape "circle"]
ask turtles-on patch -50 5
[set gradient_seed true]
end
to gradient-formation
while [true]
[
ask turtles
[
ifelse (gradient_seed = true)
[
set gradient_value 0
]
[
set gradient_value gradient_max
set color scale-color green gradient_value 0 120
ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance] ;; i consider all the turtle in talk_radius having the right gradient_distance
[
let a ([gradient_value] of self) ;; "of self" is not necessary but helped me for a better comprehension
if (a < ([gradient_value] of myself))
[
ask myself [set gradient_value a]
]
]
set gradient_value (gradient_value + 1)
]
set color scale-color green gradient_value 0 120
]
]
end
I used a scale-color in order to have a feedback of what i have done, as you can see in the image.
And now the problem: instead of let a ([gradient_value] of self), i tried set a ([gradient_value] of self) adding a to the turtle variable (I added a in the turtle-own list on top).
I thought the result would have been the same, but instead i got a constantly increasing gradient_value for every turtle as you can see in the image(the color white denotes a very high gradient_value).
Why this difference? Thank you in advance and sorry for the long question.
EDITED EXTENSIVELY in response to discussion that refined the problem
First, I would like to start with a simpler version of the code. I believe this is exactly the same as yours without the while[true]. I removed the extra 1000 turtles you are creating, and separated the ifelse on whether a seed into two separate ask statements, for clarity. I also moved the colouring until after the value calculation is complete.
globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed? gradient_value]
to setup
clear-all
resize-world -60 60 -20 20
let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape
[ sprout 1
[ set shape "circle"
set gradient_seed? false
]
]
set talk_radius 4
set gradient_max 100000
set gradient_distance 1
repeat 10 [ gradient-formation ]
end
to gradient-formation
ask turtles-on patch -50 5
[ set gradient_seed? true
set gradient_value 0
]
ask turtles with [not gradient_seed?]
[ set gradient_value gradient_max
ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance]
[ let my-gradval ([gradient_value] of self)
if my-gradval < [gradient_value] of myself
[ ask myself [set gradient_value my-gradval]
]
]
set gradient_value (gradient_value + 1)
]
ask turtles [set color scale-color green gradient_value 0 120 ]
end
There is a conceptual issue here. Until a turtle has its gradient_value calculated, it is 0. This means a large number of turtles will have a 0 turtle nearby and then have their own gradient_value as 1. It does not produce a colour gradient. To get around this, you need to run the gradient-formation several times. The approach in your code of while [true] introduces an infinite loop. Instead, you can repeat an arbitrary number of times (10 in the code above).
The problem with let versus set + turtles-won is that the set with turtles-own creates 1000 copies of gradient_value - one for each turtle. The let version creates a (temporary) global variable that all turtles access. So when you use set, you are setting it for that turtle, not as a general access number. I think what is happening is that the line set gradient_value my-gradval is accessing the wrong turtle's copy of my-gradval.
But, from the discussion, the purpose of the code that is causing the problem is to find a local minimum. There is a much more direct way of doing that.
to gradient-formation
ask turtles-on patch -50 5
[ set gradient_seed? true
set gradient_value 0
]
ask turtles with [not gradient_seed?]
[ set gradient_value 1 + min [gradient_value] of
other turtles in-radius min (list talk_radius gradient_distance)
]
ask turtles [set color scale-color green gradient_value 0 120 ]
end
ADDED a minimum working example to show the differences.
This is the let (global variable) version
turtles-own [testval]
to testme
clear-all
create-turtles 500
[ setxy random-xcor random-ycor
set color blue
set testval 1 + random 10
]
ask one-of turtles
[ set color red
inspect self
type "testval of asking turtle is " print testval
ask turtles-on neighbors
[ set color yellow
let my-testval [testval] of self ;; creates a temp global variable
type "my-testval is " print my-testval
if my-testval < [testval] of myself
[ ask myself
[ set testval my-testval ;; copies the global variable value
]
]
]
]
end
This is the set (turtle attribute) version
turtles-own [testval my-testval]
to testme
clear-all
create-turtles 500
[ setxy random-xcor random-ycor
set color blue
set testval 1 + random 10
]
ask one-of turtles
[ set color red
inspect self
type "testval of asking turtle is " print testval
ask turtles-on neighbors
[ set color yellow
set my-testval [testval] of self
type "my-testval is " print my-testval
if my-testval < [testval] of myself
[ ask myself
[ set testval my-testval ;; copies value from one attribute to other
]
]
]
]
end

Netlogo assign group of patches to own variable of a breed

I'm very new to netlogo and am wondering how I can set a group of patches to be an own variable to a certain breed. For example, let's say I have:
breed [ buildings building ]
buildings-own [ my-patches ]
I want to be able to have a set of patches (let's say a rectangle, so constrained by some coordinates) that are assigned to each individual building's my-patches field. How would I do this?
First thing you need to know is that you can't have breeds of patches. While you don't say that's what you want, I just want to make sure you are aware of this.
Have a look at this code. It is a complete program that creates some turtles (called realtors) and assigns them each some patches. It then turns those patches the same colour as the realtor.
breed [realtors realtor]
realtors-own [my-patches]
to setup
clear-all
create-realtors 10
[ setxy random-xcor random-ycor
set size 2
set shape "circle"
set my-patches n-of 5 patches in-radius 3
]
ask realtors [ask my-patches [set pcolor [color] of myself ] ]
reset-ticks
end
You can run it by creating a button for 'setup' or simply typing setup in the command centre.
Welcome to Stack Overflow and Netlogo! Given your breed and buildings-own as above, you can simply use set to assign the patch-set that you want a building's my-patches variable to hold.
to setup
ca
ask patches with [ pxcor mod 10 = 0 and pycor mod 10 = 0 ] [
sprout-buildings 1 [
set shape "square"
set heading 0
set size 1.5
set my-patches patches with [
pxcor > [pxcor] of myself - 3 and
pxcor < [pxcor] of myself + 3 and
pycor > [pycor] of myself - 3 and
pycor < [pycor] of myself + 3
]
ask my-patches [
set pcolor [color] of myself - 2
]
]
]
reset-ticks
end

Development of turtles from one breed to another

I dont know much about netlogo so this may be a really simple solution but I have multiple breeds of turtles where each breed is a different age range (eggs, hatchlings, juveniles, hawksbills (adults)) and i need them to be able to go from one breed to the next after a certain amount of ticks (in my model one tick = one day). Is this possible to code for?
Here's my code so far
globals [island]
Breed [eggs egg]
Breed [hatchlings hatchling]
Breed [juveniles juvenile]
Breed [hawksbills hawksbill]
turtles-own [
age
z
]
to setup
clear-all
set-default-shape eggs "circle"
create-eggs 80
[ set color 49.5
set size 0.5
setxy random-xcor random-ycor ]
set-default-shape hatchlings "turtle"
create-hatchlings 70
[ set color 57
set size 1.5
setxy random-xcor random-ycor ]
set-default-shape juveniles "turtle"
create-juveniles 10
[ set color 55
set size 2
setxy random-xcor random-ycor ]
set-default-shape hawksbills "turtle"
create-hawksbills 9
[ set color 53
set size 3
setxy random-xcor random-ycor ]
clear-output
setup-environment
setup-birthdays
reset-ticks
end
to setup-environment
ask patches [set pcolor cyan]
ask patches with [abs(pxcor) < 5 and abs(pycor) < 5] [set pcolor yellow]
ask patches with [abs(pxcor) < 2 and abs(pycor) < 2] [set pcolor brown]
end
to setup-birthdays
end
to go
ask eggs
[ kill-eggs ]
ask hatchlings
[ move-hatchlings
kill-hatchlings]
ask juveniles
[ move-juveniles
kill-juveniles]
ask hawksbills
[ move-hawksbills
kill-hawksbills
reproduce-hawksbills ]
tick
if not any? turtles [stop]
end
to kill-eggs
set z random 100
if z > 50
[die]
end
to kill-hatchlings
set z random 100
if z > 10
[die]
end
to kill-juveniles
set z random 20
if z > 18
[die]
end
to kill-hawksbills
set z random 5
if z > 4
[die]
end
to move-hatchlings
rt random 360
fd 1
end
to move-juveniles
rt random 360
fd 1
end
to move-hawksbills
rt random 360
fd 1
end
to reproduce-hawksbills
if pcolor = yellow
[set z random 100
if z > 75
[hatch-eggs 5[
set color 49.5
set size 0.5]
]]
end
To turn a turtle into a hatchling, just do set breed hatchlings! So, your code will probably look something like:
if age > 10 [
set breed hatchlings
]

on netlogo, how to ask turtles to set random ycor but also still be less than 1

On Netlogo, I want to create turtles and setxy to random-xcor and random-ycor but only on the green area that takes up the screen from under the ycor of 1.
If your main goal is to start turtles on a random place in the green area, you can do:
create-turtles 100 [ move-to one-of patches with [ pcolor = green ] ]
one-of patches with [ pcolor = green ] just gets a random green patch. Then, the code moves the newly created turtle to that randomly selected patch. Note that the turtles will be create on the center of the patches with this method. I recommend using this approach.
If your goal really is to set it to a random position with a maximum ycor of 1, let's first define a function that gives us a random number from between two numbers
to-report random-between [ min-num max-num ]
report random-float (max-num - min-num) + min-num
end
Now, random-ycor then does the same thing random-between (min-pycor - .5) (max-pycor + .5). The .5s are there so that the number can be at the very top or very bottom. You can use the same technique, but just replace the max-num with 1:
create-turtles 100 [ setxy random-xcor random-between (min-pycor - .5) 1 ]