I'm modeling territory colonization in Netlogo. Turtle 0 selects a territory center, then builds a territory by adding patches in order of value. Value is based on benefit / cost, where benefit is amount of food in the patch and cost is the distance from the territory center. Turtle 0 finishes building its territory once the summed patch values meets a threshold. Next, Turtle 1 sprouts and repeats the process to select its own territory, then Turtle 2, and so on. Importantly, new turtles should avoid traveling across other territories and cannot picked already-owned patches.
The Problem: Turtles need to travel around patches that are already owned. A patch's value (benefit/cost) should account for costs accurately based on the real travel distances required, not euclidean distance.
IMAGE: As a visual, here is one result from running this model. The turtle in lime green has a huge territory that required traveling over other territories and did not account for actual travel costs around what should be considered obstacles.
How might I code this to account for actual travel distance required (i.e., around obstacles of the existing home ranges) to have turtles pick patches in order of real value? Some code is below. Any ideas? Thanks in advance!
patches-own [
benefit ;; ranges 0.1-1 and represents food available in the patch
owner ] ;; patches are owned once selected for a territory
turtles-own
[ sum-value ] ;; sum of values of patches in my territory
globals [threshold = 25]
to setup
ask patches [ set owner nobody ]
end
to go
ask turtles [build-territory]
tick
end
to build-territory
if sum-value > threshold [stop] ;; keeps picking patches for territory until I've met my threshold
pick-patch
reproduce ;; sprouts a new hatchling when done building territory
end
to pick-patch
let _destination highest-value ;; this is calculated in reporters, below
ifelse _destination != nobody [
face _destination forward 1 ;; turtle will need to avoid obstacles here, haven't figured that out yet.
if patch-here = _destination
[ claim-patch _destination ]
]
[stop] ;; if there is no _destination
end
to claim-patch [_patch]
ask _patch [set owner myself]
set sum-value sum-value + (benefit / (distance start-patch))
set pcolor [color] of self
;; etc....
end
to reproduce
if sum-value > threshold [ ask patch 75 75 [sprout 1 ] ]
end
;;;; --reporters for calculations:--
to-report highest-value ;; calculates value, benefit / cost.
let available-destinations edge-patches
report max-one-of available-destinations [benefit-to-me / cost-to-me]
end
to-report edge-patches ;; constrains to searching along edge of territory so it remains contiguous.
report (patch-set [neighbors4] of territory) with [owner = nobody]
end
to-report benefit-to-me
report mean [benefit] of patches in-radius 2 ;; this is basically a moving windows analysis to find a cluster of high-benefit patches.
end
to-report cost-to-me
report distance myself ;; this is where turtle needs to account for actual travel costs (non-euclidean distance), including around other territories. how to accomplish?
end
Related
I'm trying to model predators hunting prey through a world filled with obstacles. In an obstacle free world, the predators go on random walks until prey fall within a certain detection radius (react-D), and then move towards the prey to capture. I guess there may be several ways to handle obstacles that block line of sight, but my initial efforts are along the following lines:
ifelse any? prey in-radius react-D
[let target min-one-of prey in-radius react-D [distance myself]
face target
...move towards target if it's closer than the nearest obstacle (blue patch) ahead
]
[continue to random walk, avoiding obstacles
]
The first condition of ifelse may need another ifelse. In any case I think I just need a distance of the nearest blue patch ahead to compare with the target distance, but it's not clear to me how I can get that from patch-ahead.
It would be nicer if I could put all this into the test of the first ifelse, but something like the following doesn't allow for patches that aren't blocking line of sight to the prey:
ifelse any? prey in-radius react-D and min-one-of (patches in-radius react-D with [pcolor = blue])[distance myself] > min-one-of (prey in-radius react-D) [distance myself]
Line of sight is actually really tricky to model in NetLogo. At the moment I do it by creating a turtle (invisible, separate breed called crawler) where the agent is that is looking and have the crawler move ahead in small steps checking the colour of the patch that it is on. That goes inside a while loop and the crawler stops when it finds the wrong colour or when it gets to the target distance. the crawler has to take small steps because crossing over the corner of a patch should still block it and it's a trade-off between resolution (how small the crawler step is) against efficiency.
You can almost certainly do the same thing by creating a patch-set as the union of patches found with patch-ahead of multiple distances like 0.1, 0.2, .... and then checking any? over that patch-set
My current solution, giving patches-own [ ob ] values of 1 to all obstacle patches, then using while to detect obstacles ahead:
to detect-ahead
let dist 1
let last-patch patch-here
while [dist <= react-D] [
let p patch-ahead dist
if p != last-patch and [ob] of p = 1 [
ask p [ sprout-markers 1 [ set color yellow ] ]
set last-patch p
]
set dist dist + 1
]
end
Then it should simply be a case of comparing min-one-of the marker agent set with the target. Obviously smaller increments would be good, as JenB says.
hope you can help me out! I have a NetLogo question about the following code:
breed [tourists tourist]
turtles-own [satisfaction]
to setup
clear-all
reset-ticks
end
to go
tick
ask n-of initial-number-tourists patches
[
sprout 1 [
set color white
set size 1
]
]
ask turtles
[ let nearest min-one-of turtles [distance myself]
if-else distance nearest < 0.0000001 [ set satisfaction 0 ]
[ set satisfaction 1 ]
]
ask turtles with [satisfaction = 0] [die]
end
The intention is to sprout "initial-number-tourists" at the start of each tick. Then, they calculate their 'satisfaction' based on the if there are turtles close and let the turtles that have a satisfaction of 0 die. Then, the turtles that remain (that are satisfied) will be sprouted again and their satisfaction will be calculated again.
The code is working, however, with unexpected outcomes. What happens is that the turtles are all sprouted, and they all die each tick. The next tick; they are sprouted again and all die again. Even if i set the distance threshold really low like i did in the code I provided.
Hopefully you can help me out!! Kind regards
The problem you are encountering is that the nearest turtle to each turtle is itself! Thus the distance to nearest is always zero and satisfaction will be set to zero for every turtle. What you want is the closest among the other turtles,
let nearest min-one-of other turtles [distance myself]
(Your distance threshold will mean that all turtles will have satisfaction of 1, but I assume that is what you wanted to accomplish in your testing. Since turtles are sprouted at the centers of the patches, a threshold of < 1.0 would accomplish the same thing.)
Minor point: the convention is to put tick at the end, not the beginning of the go procedure.
I want to limit number of turtles per patch. I thought if I restrict movement of turtles as per the (1) and (2) conditions it will limit number of turtles per patch but whatever code I tried for this till now did not worked.
Let's suppose there are five turtles on patch Y and five is the limit.
1) to ask turtles standing at front on patch X (refer figure) to stop moving till there are five turtles on patch Y (refer figure).
2) to ask turtles standing at front on patch Y to move forward to patch z (refer figure) if patch z has less than five(5) turtles on it else stop.
At last I am using following simple code
let turtles-ahead other turtles in-cone speed 90
let turtle-ahead min-one-of turtles-ahead [distance myself]
ifelse turtle-ahead != nobody
[
set speed [speed] of turtle-ahead
slow-down
]
[speed-up]
This code simply ask turtles to move one-behind-another pattern or queue but it does not help me to limit number of turtles per patch whatever limit may be 4,5,6,7, 8... I have sprouted turtles within "go" procedures (1 turtle per patch, as per my need). The turtles are sprouted on a defined set of patches not in the whole world. So slowly number of turtles starts increasing and move around the world and after certain amount of ticks they are ask to exit out of the defined area and they die. Now at times it shows 10,11,.... 37 or above turtles on certain patches and this I want to stop actually.
I have checked one-turtles-per-patch, other code examples and many other helps from internet but no results.
For any other idea or help I would be obliged. Please help me.
I think you want to have turtles assess the count of turtles-here of the patch to which they are trying to move. Consider this simple example:
to setup
ca
ask n-of 15 patches with [ pycor = 0 ] [
sprout 3 [
set heading 90
]
]
reset-ticks
end
to go
ask turtles [
if ( count [turtles-here] of patch-ahead 1 ) < 5 and xcor < 16 [
fd 1
]
]
print [count turtles-here] of patches with [ any? turtles-here ]
tick
end
On each tick, the turtles with an xcor of less than 16 (just to set a stop for this example) all check the patch-ahead 1 for the count of turtles on that patch. If the count is less than 5, the turtle moves to that patch. Otherwise, the turtle does nothing.
Model Details I'm attempting to code territory selection in NetLogo. Turtle 0 selects a territory center, and builds a territory. It select patches based on value of food, discounted by the distance away (food / # patches away from center of the territory), selecting patches in order of discounted value. It stops when it meets total food requirements. Patches selected don't have to be connected to the territory, but should become connected as the turtle walks to the selected patch. These patches crossed are added as travel corridors so that the territory remains contiguous. After Turtle 0 has finished building its territory, Turtle 1 sprouts and repeats the process to select its own territory, then Turtle 2, and so on. Patches belonging to a turtle's territory are unavailable to other turtles.
The Problem Existing territories should be seen as obstacles. Turtles need to identify and go around these obstacles to reach their destination patch using the shortest path possible.
In my current code, turtles will select patches on the other side of an existing territory because they just travel across it. They won't have added a travel corridor to get there, however, because the patches on the way there were already owned.
What are some ways I might tell turtles that if they encounter owned patches (existing territories), they must go around using the shortest distance possible so they can build a travel corridor to the selected patch? I realize this is a complex question, made even more so if actual distances are calculated in (connected question: NetLogo: measure real travel distances around obstacles before choosing destination). I've been racking my brain on this one, so any ideas are helpful. Thanks in advance!
patches-own [
benefit ;; ranges 0.1-1 and represents food available in the patch
owner ] ;; patches are owned once selected for a territory
turtles-own
[ sum-value ] ;; sum of values of patches in my territory
globals [threshold = 25]
to setup
ask patches [ set owner nobody ]
end
to go
ask turtles [build-territory]
tick
end
to build-territory
if sum-value > threshold [stop] ;; keeps picking patches for territory until I've met my threshold
pick-patch
reproduce ;; sprouts a new hatchling when done building territory
end
to pick-patch
let _destination highest-value ;; this is calculated in reporters, below
ifelse _destination != nobody [
face _destination forward 1
if patch-here = _destination ;; add the patch once reached
[ claim-patch _destination ]
if patch-here != _destination
[ if owner = nobody [claim-travel-patch ]] ;; add a travel patch while walking to selected patch
[ if owner != nobody [avoid-obstacle]] ;; or avoid the obstacle of existing territories
]
[stop] ;; if there is no _destination
end
to claim-patch [_patch]
ask _patch [set owner myself]
set sum-value sum-value + (benefit / (distance start-patch))
set pcolor [color] of self
;; etc....
end
to claim-travel-patch [_patch]
ask _patch [set owner myself]
set pcolor [yellow]
;; etc....
end
to avoid-obstacle
;; need to identify some means of going around owned patches
;; ideally this will use the shortest route possible....
;; but even if not shortest route, any ideas for identifying a new path
;; to avoid the obstacle and reach the destination patch?
end
to reproduce
if sum-value > threshold [ ask patch 75 75 [sprout 1 ] ]
end
;;;; --reporters for calculations:--
to-report highest-value ;; calculates value, benefit / cost.
let available-destinations patches with [owner = nobody]
report max-one-of available-destinations [benefit-to-me / cost-to-me]
end
to-report benefit-to-me
report mean [benefit] of patches in-radius 1 ;; this is basically a moving windows analysis to find a cluster of high-benefit patches.
end
to-report cost-to-me
report distance myself ;; later, this will hopefully account for actual travel costs (non-euclidean distance), including around other territories. I think this is complicated, so ignoring for now in this question.
end
I am currently learning NetLogo and I need help. In my model I have same sized 10 turtles which moves randomly. When 2 or more turtles are on the same patch they will combine and form a new turtle with the double size. In this manner, the main rule is max. 5 turtles can combine to each other. And this formation will continue until the there will be 2 turtles (with each contain 5 turtles) remain.
I had created turtles and made them move randomly, but I could not managed to combine them. Can you show me a way to do this? Any help appreciated. Regards.
EDIT: I tried the "in-radius" command unsuccessfully. 5-5 distribution of the turtles (as you can can see from the code, they represent H2O molecules) is vital for the system definition and any other distributions are not allowed in the model.
In detail, when randomly moving 2 H2O molecules meet on the same patch, they will combine to form a new molecule (2H2O). The main rule is as previously mentioned, max. 5 molecules can combine which ends with forming 5H2O. Since, initially there are 10H2O molecules in the system, there will be 2 5H2O molecules at the end.
The code I tried to implement is as follows,
breed [h2o-molecules h2o]
to setup
clear-all
reset-ticks
create-h2o-molecules h2o-num [
set color 105
set sIze .5
set shape "circle"
setxy random-xcor random-ycor
set pen-mode "up"
]
end
to setup-patches
ask patches [set pcolor 0]
show count turtles
end
to set-label
ask patches [
ifelse count turtles-here > 0
[set plabel count turtles-here]
[set plabel ""]
]
end
to move-h2o-molecules
ask h2o-molecules [
let dice random 1000
let change (dice - 1)
forward 2
set HEADING (HEADING + change * 2)
]
end
to go
setup-patches
move-h2o-molecules
ask turtles [rt random 1
fd 0.3]
set-label
tick
end
Thanks for your time and patience. Regards,
Using turtles-here
You don't need to ask patches for turtles-here (as you did to set patches labels). The function runs as well if called by a turtle (and is more efficient when there are more patches than turtles). But take care to use other turtles-here if you don't want to include the calling turtle.
Combine procedure
If you declare
a turtle variable after your breed declaration:
h2o-molecules-own [
turtles-inside
]
(set the variable value inside your create-h2o-molecules)
and your combination limit max-inside as a global variable (use slider widget with 5 as default value)
then the combine procedure can look like:
to combine ;; turtle procedure
; take one turtle from the same patch as a target
; which has turtles-inside low enough to combine with
let target one-of other h2o-molecules-here with
[turtles-inside <= max-inside - [turtles-inside] of myself]
if target != nobody
[
set turtles-inside turtles-inside +
[turtles-inside] of target ;; increase turtles-inside
ask target [ die ] ;; kill the target
set size sqrt turtles-inside ;; increase size
]
end
Stop
You can stop the simulation by
if not any? h2o-molecules with [turtles-inside < max-inside] [ stop ]
Comment
The condition used to select the target turtle is using turtles-here, other and the maximum constraint which is compared to the sum of turtles inside the target and turtles inside the calling turtle (using myself function).