How to specifically change a variable of an agent in the agentset? - netlogo

I am trying to change a variable (score) of a particular agent in the agent set if it meets the specific condition of a patch. This is called by an another agent. To be more clear. My idea is for instance if there is a breed (horse) and it sees the patch (grass) and it is standing on another breed (vertices - since horse move along a path connected by nodes represented by vertices) - a score variable to added to vertices-own where if the grass quality <=3, it would add a score to the vertex on which it stands.
ask horses[
ask patches in-cone 50 60 [
if grass-quality <= 3 ask vertices with [min-one-of vertices in-radius 0 [distance myself] [set vertex-score vertex-score + 1 ]]]]
I know something is wrong with this code logic. I am trying to convert my mentioned thought into codes. Kindly suggest me.
Thank you all.
Regards,
Heng wah

NetLogo agent (turtle) positions are continuous numbers so it is generally wrong to try and say something like 'if another turtle is where I am'. While you may have got there using move-to, it's probably safer to have the horse identify a vertex that is very close to it rather than in the exact position. You have used radius 0 but I'm going to change that to 0.001 to allow for potential errors in position.
ask horses
[ if any? patches in-cone 50 60 with [ grass-quality <= 3 ]
[ let my-vertex min-one-of vertices in-radius 0.001 [distance myself]
ask my-vertex
[ set vertex-score vertex-score + 1 ]
]
]
]
This is not tested, but I have simply reorganised your code. You had some bracketing issues and you were also asking vertices to find the closest vertex (which would have been itself), rather than having the horse find the closest vertex.
It's also not necessary to separate the let and the ask but I thought that would be easier for you to see how it works.

Related

Netlogo: subtracting previously diffused values

Is it possible to subtract previously diffused values?
I have a land-use model where residential use (yellow patches) diffuses its land value with the diffuse primitive:
diffuse land-value 1
In the first image below, land value is represented as white tones, the brighter the tone, the higher the land value. Residential use sometimes abandons the patch, but their land value influence stays (second image). Is there a way that, when the land use disappears, the value it previously diffused to all patches be subtracted and also disappear?
Following comments under the question and following Luke's suggestion of framing the diffusion of land-value as a function of distance instead of a recurring diffuse, I have set up the following solution (in point 1).
Below (in point 2), you find a possible approach (not fully coded, but sketched-out enough) for addressing the issue if you want to stick to diffuse.
1 - Approach with function of distance
What happens here is that, when a patch gains residential status (to create-residence), all other patches in a certain radius calculate how much spill-over land-value they get based on the residential value of the new residential patch and on how much it is distant (to-report diffused-value).
The advantage of this approach is that this calculation is fully replicable at any moment because it is based on two constants: the distance between patches and the initial residential value of the patch in question (for which I created the patches-own own-residential-value, distinct from the general land-value).
For this reason, when a patch loses residential use (to dismantle-residence) it is possible to perform the same calculation but, instead of having patches add diffused-value to their land-value, they will subtract it.
I think the code I place below best illustrates its functionality if you create the create-residence and dismantle-residence buttons in the Interface, and play with them to see how overlapping land-values add and subtract in the View.
globals [
; Agentsets for patches.
residence
non-residence
]
patches-own [
land-value
own-residential-value
]
to setup
clear-all
set non-residence (patch-set patches)
set residence (patch-set)
end
to create-residence
let new-res one-of non-residence
ask new-res [
set non-residence (patch-set other non-residence)
set residence (patch-set self residence)
set own-residential-value (random 10) + 1
set land-value (land-value + own-residential-value)
set pcolor yellow
diffuse-value
]
update-colours
end
to diffuse-value
ask other patches in-radius 10 [
set land-value (land-value + diffused-value)
]
end
to dismantle-residence
let target one-of residence
ask target [
set residence (patch-set other residence)
set non-residence (patch-set self non-residence)
; As opposed to 'to create-residence', where 'diffuse-value' is at the end of this block of commands,
; here 'subtract-value' has to be placed before the patch updates its 'own-residential-value' to 0,
; because that value is needed to calculate 'diffused-value'.
subtract-value
set land-value (land-value - own-residential-value)
set own-residential-value 0
]
update-colours
end
to subtract-value
ask other patches in-radius 10 [
set land-value (land-value - diffused-value)
]
end
to-report diffused-value
; Here, 'myself' is the new residential patch (as 'new-res' in 'to create-residence') or
; the new non-residential patch (as 'target' in 'to dismantle-residence').
let d distance myself
let v [own-residential-value] of myself
report v * (0.9 / d) ; Just an arbitrary function of value and distance.
end
to update-colours
ask non-residence [
set pcolor scale-color white land-value 0 15
]
end
2 - Approach if sticking to diffuse
I have though of an approach for this case too, but I also want to understand if diffuse really is what you want to use.
As we know, diffuse is a zero-sum game: what is diffused by a patch is also lost by a patch.
Therefore, I imagine you will not be just using diffuse land-value 1, because in that case land-value of the residential patch will be 0 after one tick, will very slightly recover on the subsequent tick, and will then progressively approach 0 from the third tick on.
For example, the following code gives the results as in the table below:
patches-own [
land-value
]
to setup
clear-all
reset-ticks
ask patch 0 0 [set land-value 50]
end
to go
diffuse land-value 1
tick
end
I doubt this is anything you are interested in replicating, so I assume the approach would be something like:
patches-own [
land-value
temp
]
to setup
clear-all
reset-ticks
ask patch 0 0 [set land-value 50]
end
to go
diffuse-value
tick
end
to diffuse-value
ask patches [
set temp land-value
]
diffuse land-value 1
ask patches [
set land-value (land-value + temp)
]
end
However, I think that even in this case diffuse seems to be not fit for representing a residential value spreading to near-by areas. By using the code above, in fact, the result is the following:
The table above shows that, in 15 ticks, the patch which should be the one diffusing some value in the area experienced a 93593% increase (no, I didn't forget any decimal point!) in its land value. I know of course this might be mitigated with some formula, but I think it shows the tendency of diffuse in this case: to create an escalating positive feedback between patches, so that a small residential value grows without control.
I'm not the expert of residential values here, but I felt these results (from both the former and the latter use of diffuse) were worth pointing out from a NetLogo perspective.
That said, if the idea is to stick to diffuse...
patches-own [
land-value
own-residential-value
residential-start
temp
]
to setup
; Some code.
end
to go
; Some code.
end
to create-residence ; Executed by the observer. This procedure cannot be executed by the patch becoming residence because it contains 'diffuse'.
let target ; <- Identify here the patch that needs to become residence.
ask target [
; Set 'own-residential-value' to something.
set land-value (land-value + own-residential-value)
set residential-start ticks
]
; Have some code here that uses 'diffuse own-residential-value'.
end
to dismantle-residence ; Executed by the observer. This procedure cannot be executed by the patch being dismantled because it contains 'diffuse'.
ask patches [set temp 0] ; This is crucial in order to avoid any overlap among patches when using 'diffuse'.
let target ; <- Identify here the patch that needs to be dismantled.
let time-as-residence (ticks - [residential-start] of target)
ask target [
set temp own-residential-value
]
repeat time-as-residence [
; Insert here the exact same code that
; was used for using 'diffuse' but
; diffusing the 'temp' variable instead
; (e.g. 'diffuse temp 1').
]
ask patches with [temp > 0] [
set land-value (land-value - temp)
]
end
What happens above is that, whenever a patch loses residential use, the program performs exactly the same number of diffuse operations as it performed when actually diffusing land-value during the residential life of the patch at stake, but on temp instead of land-value. This way, all the surrounding patches will store in temp the same value they gained over time from the patch being dismantled - so they can subtract this value from their current land-value.
The success of this approach depends on the ask patches [set temp 0] statement: given that diffuse operates on each patch, by setting all temp to 0 and then doing ask target [set temp own-residential-value] we make sure that we only reproduce the pattern of value-diffusion that can be attributed to the patch being dismantled - avoiding any overlap that might have occurred over time, when patches may have gathered (and then re-diffused) value from other residential patches.
(This is based on the assumption that you use diffuse at every tick, as you said in a comment to the question. Even if that ceases to be the case, it will be easy to set time-as-residence in an alternative way according to the number of times that diffuse took place since a particular patch became residential)
Potential problem This is something that you will have to untangle yourself, but consider that there remains a possible issue: you have to decide whether you want to diffuse own-residential-value or land-value, with both options presenting some problem.
Diffusing own-residential-value seems intuitive to me, since that is the added value; however, this means that the diffused value would go into own-residential-value of the other patches (and not into their land-value) even if they really do not have any residential value of their own, which will create the need for extra computation (a possible option could be to rename own-residential-value to something more appropriate, like residential-value, and create a further tot-value patches-own variable that is updated at every tick as set tot-value land-value + residential-value).
On the other hand, diffusing land-value would be more straightforward in terms of coding (land-value would just propagate to other patches' land-value) but seems less precise based on what I can understand, given residential patches would be propagating land-value which often will not be just the new residential value that they bring, but also the result of that positive feedback discussed before, building on other patches' residential values.
Conclusions
While I'm quite confident that the second approach is viable and technically good, I definitely prefer the first based on the doubts that I expressed over the use of diffuse for this particular goal (at least based on the understanding I have of your intentions, which I might not understand fully) - and the feeling that a function of distance looks like a neat approach to diffusion of value in this scenario.

NetLogo : getting turtles to direct-link if a condition is true

I'm trying to implement YOYO leader election algorithm in netlogo
first step in this algorithm is to orient links ( direct link )from the minimum to the maximumbut between neighbors only !
I tried the command
[`ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors ]`
this creates direct link from min to max ( neighbors ) but also creates a direct link from max to min ( neighbors )
and I don't know what's wrong :(
here's a screenshot , if you notice theres' a direct link from 0 to 2 and also from 2 to 0 and my goal is to have only from 0 to 2
Your problem is that every time you do one-of, it randomly selects. So you test against a random link-neighbor in the first line, find it's true and then randomly select a link-neighbor to connect to.
[ ask turtles with [ [ who ] of self < [who] of one-of link-neighbors ]
create-direct-to turtle [who] of one-of link-neighbors
]
More generally, this seems an odd way to achieve your goal. To start with, link-neighbors are the turtles that the turtle is already linked to. link is the generic name for all link breeds (I think you have created a breed called direct-link).
I am not entirely clear what you mean by minimum and maximum since your code is just from smaller to larger who value, regardless of what other who values are available. If you want to create a link from every turtle to every turtle with a higher who value, here is some code:
ask turtles
[ let targets turtles with [who > [who] of myself]
create-links-to targets
]
In general, it is bad practice to use who in NetLogo code. who is a completely arbitrary identifier that simply tracks the order that turtles are created. If you have turtles that die, then your code may crash because it is referring to a turtle that no longer exists. Or perhaps at some point you will have two breeds of turtles - who doesn't care if your turtle is a person or a dog or a factory or...
This may be one of the very few exceptions, but you might want to think about what you are intending who to mean. For example, as this is a leadership model, perhaps you could have a variable called 'charisma' and all the links are from turtles with lower values of charisma to higher values of charisma.

Constraining Movement of Agents to a Home Range in Netlogo

I'm relatively new to NetLogo, and I'm working to model moose density in New Hampshire and its correlation to winter tick parasitism.
I'd like to program my moose agents to move randomly within a set home range (~5km2), that originates from the randomly chosen patch they first enter the model on.
I'm not really sure how to bound agents based on area, rather than just patch color... Any suggestions on how to do this would be most appreciated!
Thank you!
General stackoverflow tip: typically, stackoverflow encourages specific programming questions. So including the code you've actually tried so far is generally preferred.
Alright, on to your problem.
One really simple way to do this is, first, store the mooses' starting patch. Second, when the moose is moving around, check the distance to the starting patch. If the distance exceeds the starting amount, have the moose towards the starting patch. Here's some template code to give you ideas:
breed [ mooses moose ]
mooses-own [
starting-patch
]
to setup
clear-all
;; only using one moose as it's easier to see the behavior
create-mooses 1 [
setxy random-xcor random-ycor
set starting-patch patch-here
]
reset-ticks
end
to go
ask mooses [
move
]
tick
end
to move
;; If farther than 10 patches from starting patching, take a step towards starting patch, otherwise, move randomly
ifelse distance starting-patch > 10 [
face starting-patch
] [
rt random 90
lt random 90
]
fd 1
end

getting turtles to consider other turtle's variables

I am new to Netlogo and have become stumped with a problem.
I have written a model where one breed of turtles (wombats) randomly chose to move-to different burrows (a second breed of turtles). However, I now wish to make it so that the quality (represented by a number) of the burrow currently on the same patch as a wombat influences the probability of the wombat moving to a different burrow. I had envisaged this to look similar to:
ask wombats[
if random-float 100 >= burrow-fidelity * ( quality one-of burrows burrows-here / 2)
[move-to one-of burrows with [not any? wombats-here]]
]
however this does not work.
Is there anyway that I make the wombat report the size of the burrow currently sharing the same patch (there is only ever one burrow per a patch) and then make the wombat incorporate the reported value into the above equation where "quality one-of burrows burrows-here" is?
Thank you in advance
To report the value of another agent's variable, use the of keyword:
[ quality ] of one-of burrows-here

Count neighbors turtles of a specific patch and report true or false

Hello i will try to be quick
I have a room with a fire that expands , and i have two exits , all i want to do is say to agents that if a door is blocked by fire then to go to the other one. i came up with something like this but not result.
to doorblock
show count neighbors with [pcolor = 77] ;; the patch color of the two doors
end
;;to go
ask smarts [ ;;smarts are the agents inside the room that need to get oout
if [ doorblock > 5 ]
[ set target one-of sexits]] ;;sexits is the other door
Anyone got a better idea? Thanks
OK, so if I understood correctly, you want your agents to take a look at the door that is their current target, check if that door has more than 5 fire agents around it, and choose another target door if that is the case.
If your fire agents are just red turtles (with no specific breed), you probably want something like this:
ask smarts [
if count ([ turtles-on neighbors ] of target) with [ color = red ] > 5 [
if-else ([ breed ] of target = sexits )
[ set target one-of nexits ]
[ set target one-of sexits ]
]
]
The key primitives here are:
neighbors, that will give you the patches around a turtle (the patches around target, in this case)
turtles-on, that will give you the turtles that are on members of a patch set (here, that will be the turtles that are on the patches that are the neighbors of target)
and finally, with allows you to get only the turtles from an agentset that satisfy some condition (here, we use it to get only the red turtles that represent the fires).
You should also try to understand the of primitive.
And I guessed you wanted to assign a new target that was of a different breed than the previous one (south if north, north if south) but that's up to you.