Ask turtles to face set of patches with highest summed value - netlogo

I am working in NetLogo on an animal movement model. I have created six different agentsets that contain the patches in-cone 16 60 (asking my turtles to turn rt 60 before calculating the next agentset). I have then asked each agentset to calculate the sum of weighted-index (a patch variable between 0-1) and save the value into a global variable. So now I gave six areas surrounding each turtle, and a value that represents the resource value of that entire agentset to the turtle. I am trying to get my turtles to recognize what agentset has the highest sum of the weighted index and move to a random patch within it. I am running into issues because the global variable that represents the summed weighted index is not attached to the location of the agentset so I don't know how to move on from this step. My only idea is to do a complicated ifelse chain where I ask turtles to compare the summed values and face the agentset corresponding to that value, but this seems pretty lengthy. Any ideas or suggestions on how to solve this or make my question clearer are much appreciated!
I have tried to make a list and call for with-max but again, this reports the max sum as a number, not the agentset to which it belongs to.
; This code gets called in my go procedure as ask bears []
;I am first creating the agentsets
set heading 0
set n-patches patches in-cone 16 60
rt 60
set ne-patches patches in-cone 16 60
rt 60
set se-patches patches in-cone 16 60
rt 60
set s-patches patches in-cone 16 60
rt 60
set sw-patches patches in-cone 16 60
rt 60
set nw-patches patches in-cone 16 60
; Now I'm adding the index value for all patches within each agentset
set n-sum sum [weighted-index] of n-patches
set ne-sum sum [weighted-index] of ne-patches
set se-sum sum [weighted-index] of se-patches
set s-sum sum [weighted-index] of s-patches
set sw-sum sum [weighted-index] of sw-patches
set nw-sum sum [weighted-index] of nw-patches
; Lost after this

First thing, there's no need to use global variables, just use let to create a temporary local variable.
This is a surprisingly tricky problem because you can't use any of the built in primitives that find the maximum within an agentset and list primitives don't have that capability.
I have written a standalone model that demonstrates what you want. It uses pcolor as the value instead of the weighted index, and I chose colours that get darker as the number increases.
to testme
clear-all
ask patches [ set pcolor one-of [ 28 54 110 ] ]
create-turtles 3
[ setxy random-xcor random-ycor
set color white
]
ask turtles
[ set heading 0
let n-patches patches in-cone 16 60
rt 60
let ne-patches patches in-cone 16 60
rt 60
let se-patches patches in-cone 16 60
rt 60
let s-patches patches in-cone 16 60
rt 60
let sw-patches patches in-cone 16 60
rt 60
let nw-patches patches in-cone 16 60
let directions-list shuffle (list n-patches ne-patches se-patches s-patches sw-patches nw-patches)
print directions-list
let sums-list map [ thisDir -> sum [pcolor] of thisDir ] directions-list
print sums-list
let max-sums max sums-list
print max-sums
let chosen position max-sums sums-list
print chosen
face one-of item chosen directions-list
]
end
You could use a to-report procedures to simplify the calculation of the six agentsets, but I haven't done that as I wanted to use your code to help keep it readable
This prints things out so you can see what it's doing. Note that the shuffle is to ensure random selection if 2 or more happen to have the same totals. Remember that NetLogo lists are 0-indexed, so position will return 0 to 5, not 1 to 6.
What it does is puts the agentsets into a list, calculates the value of the sums (using map) for each item on the list and puts those sums into a new list in the same order. It then searches for the maximum of that new list, finds the position of that maximum, uses that position to extract the correct agentset from the first list, and then faces a random patch within that agentset.

Related

Resize grid in the world based on number of turtles (input) and link specific breeds together

I would need to visualize the below turtles (from three different breeds) in a squared grid where links are only between turtles from the same breed, except for breeds types2 and types3, that can be also linked to each other.
So what I would like to have is a 2D grid where the number of turtles per each type is
40% of type1
40% of type2
20% of type3
(in total 100 turtles).
set-default-shape types1 "circle"
set-default-shape types2 "circle"
set-default-shape types3 "triangle"
ask n-of 100 patches [ sprout-types1 1 ]
ask n-of (100 * 0.4) types1 [set breed types2]
ask n-of (100 * 0.2) types1 [set breed types3]
the values are ok but the turtles are 'free' in the world, not displayed on a grid.
How can I display them into a grid and link them based on the above conditions?
This answer Different types of turtles in a lattice grid has provided some help on this, but the resize of the grid and the number of turtles are not the expected ones.
You should resize the world before creating agents.
That is, from the perspective of the code's workflow: if you want to have n agents, then n is first and foremost the number of patches. Then, once this is the case, all patches will sprout.
You need the resize-world command.
You mentioned that you want to have 100 turtles, that is 100 patches, that is a 10x10 world.
This means that you could do:
to setup
clear-all
resize-world 0 9 0 9 ; This creates a 10x10 world.
set-patch-size 30
ask patches [
sprout 1 [
set shape "circle"
set size 0.5
]
]
end
The code above works as long as you are happy for your world to be the size of exactly 100 patches, given that the size = 100 is hard-coded.
You might want to think about some way to accomodate a change in the number of agents.
For example, the approach below works as long as the number of agents is the perfect square of an integer:
globals [
n-agents
]
to setup
clear-all
set n-agents 100
let side-length n-agents ^ (1 / 2) - 1
resize-world 0 side-length 0 side-length
set-patch-size 30
ask patches [
sprout 1 [
set shape "circle"
set size 0.5
]
]
end
After all the point is that the shape of the world in NetLogo can only be a square or a rectangle; i.e. you cannot have a NetLogo world that is made of a prime number of patches (only exception being a world whose world-height and/or world-width equal 1).
So, in order to have your code be the most accomodating to changes in n, you could come up with more elaborated steps that resize the world based on n so that it gives you n patches even when n is not a perfect square; but for example, unless you are happy to have a monodimensional world, you can never have 53 patches. However, since you are talking of grids, I think this shouldn't be a problem for you.

NetLogo - In-Cone radius

ask turtles
[ ask patches in-cone 3 60
[ set pcolor red ] ]
The code above means to have a cone of radius 3 and angle of 60 degrees. But I want a radius in range of 5 to 10. Is there a way to accomplish this?
What you can do is set up a variable that will hold the radius's that you have asked for. Let's call this variable vision. So,
let vision
set vision 5 + (random 5)
and then you can substitute vision instead of the 3 in your code.
ask turtles in-cone vision 60 [
set pcolor red
]
Here are a couple of ways you could do it. These are adapted into the Vision Cone Example model that comes in the models library with NetLogo, so we're using slightly different distances (between 9 and 30) to make the effect visually obvious. I'd recommend method1, but I'm including method2 as it's useful if you have some alternate logic to apply to the patches that are too close.
to method1
; use `distance` to filter those that are too close
; `myself` refers to the turtle doing the asking
ask patches in-cone 30 60 with [distance myself >= 9] [
set pcolor grey
]
end
to method2
; create a local variable to store the turtles that
; will be too close. `self` refers to the patch
; being asked
let too-close patches in-cone 9 60
ask patches in-cone 30 60 with [not member? self too-close] [
set pcolor gray
]
; I could use the `too-close` agentset here and ask them
; to do something, also.
end

How to limit number of turtles in a patch in NetLogo

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.

NetLogo: Combine and form a new turtle

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).

In-Cone only works for patch centers Netlogo

I'm having some issues with the in-cone command in Netlogo. I am trying to identify the sum / mean of all the patch variables directly in front of my turtles current location (ie the sum of all the variables it crosses). However, this only appears to be working when my turtle is at the center of a patch (co-ordinates are integers not decimals), which also means I can only move my turtles at right angles. I'm yet to find any other questions pertaining to the same issue on Stackoverflow or elsewhere. So if anyone could offer some insight, I'd be greatly appreciative.
Below is the simple sample code. And I've annotated where making the changes causes this to not work.
Cheers
Paul
turtles-own [value]
patches-own [value-test]
to Set-Up
ca
reset-ticks
ask patches [if pycor > 150 [set value-test 1]]
ask patches [if pxcor > 150 [set value-test 1]]
ask patches [if value-test = 1 [set pcolor red]]
create-turtles 1
ask turtles[
;It works when the turtle is created at the origin (0 0), or at defined coordinates (but not random-xcor random-ycor)
;setxy random-xcor random-ycor
set value 0
set size 10
set color yellow]
end
to go
ask turtles[
;heading has to be 0, 90, 180, or 270.
set heading 270]
ask turtles[
let test mean [value-test] of patches in-cone 10 1
print test
print xcor
print ycor
ask patches in-cone 10 1 [set pcolor blue]
forward 10]
end
in-cone is not the right tool for the job. Unfortunately, NetLogo doesn't have a primitive that looks ahead in a straight line. It does, however, have patch-ahead, which reports a single patch at a given distance. We can use that to build something similar to what your looking for:
to-report patches-ahead [ dist step ]
report patch-set map patch-ahead n-values (dist / step) [ step + ? * step ]
end
This code may look puzzling at first, but what it does it actually quite simple:
It uses n-values to build a list of incrementing values: n-values (dist / step) [ step + ? * step ]. For example, if dist was 1 and step was 0.2, you'd get [0.2 0.4 0.6 0.8 1]. These values represent the distances at which we are going to be looking for a patch.
It uses map to call patch-ahead for each of values in the list and build a list of patches. Note that this list can contain duplicate patches, especially if step is small, since patch-ahead 0.1 and patch-ahead 0.2, for example, may very well be the same patch.
It uses patch-set to turn that list in a proper agentset of patches, without duplicates.
(You could achieve the same thing with a while loop and an incrementing counter, but the code would be longer, more error prone, and much less elegant.)
To use it, just replace instances of patches in-cone 10 1 in your code by something like patches-ahead 10 0.1.
You will notice that there is a trade-off between precision and speed: the smaller step is, the less likely it is to "skip" the corner of a patch, but the longer it will take to run. But I'm sure that you can find a value that works well for you.
Nicolas has a much better answer solving the problem of looking in a straight line but if you simply what look at the patch directly ahead use patch-ahead 1 it works at all angles and coordinates and is much faster than in-cone.
Completely an aside but probably the reason you found this bug is because your cone was set to 1 degree wide and 10 patches long. Long narrow cones tend to break up.