NetLogo - compare single agent against many agents (expected input not list) - netlogo

I am first time poster, six month reader. I love this site and am grateful for the vast array of topics covered. Now that I am feeling a bit more competent using NetLogo, I've tried some harder stuff and got stuck...
Basically, I have created a membership function which measures agents against one another on a vector containing two variables (opinions on rock and hip-hop):
to-report membership [ agent1 agent2 ]
let w 0.5
let w2 sq w
report exp (- d2 agent1 agent2 / w2)
end
where
;;;;;;;;;;;;;;Shortcut functions;;;;;;;;;;;;;;;;;;;;;;;;;;;
to-report d2 [agent1 agent2 ]
report ( (sq ([rock] of agent1 - [rock] of agent2)) + (sq ([hip-hop] of agent1 - [hip-hop] of agent2)) )
end
to-report sq [ x ]
report x * x
end
This all works fine, and I am able to compare any two agents without problem.
However, my trouble arises when I try to compare a single agent [agent1] with all of the agents within his neighbourhood.
to go
ask turtles [
let neighbours turtle-set turtles in-radius neighbourhood
show membership self neighbours]
end
Whenever I run this model I receive an error that the d2 reporter expected an input not a list - which I theoretically understand - by having a neighbourhood of 1+ agent(s), the calculation is receiving for example [0.1 0.8] [0.2 0.4] [0.5 0.6]..............
I was just wondering, is there any way that the procedure can consider all of the neighbours and arrive at one single membership number? I have searched extensively through posts and a couple of netlogo books I have, but no luck so far. Thank you for taking the time to read this post and for any helpful comments.

Your understanding of what is happening is correct: your membership reporter expects two individual agents and you are passing it an agent and an agentset. To calculate each membership individually, and get back a list of membership values, you can use of:
to go
ask turtles [
let neighbours turtle-set turtles in-radius 10
show [ membership myself self ] of neighbours
]
end
Notice the use of myself and self, which can sometimes be tricky to understand. In this case, self is the neighbour and myself is the outer asking turtle.
So now you have a list of membership numbers, but you wonder:
is there any way that the procedure can consider all of the neighbours and arrive at one single membership number?
There are plenty of ways! But we can't really tell you which one to use: it depends on your model and what you want to do with it.
If you wanted something very straightforward, you could just take the mean of the list:
show mean [ membership myself self ] of neighbours
...but I don't know if it makes sense in your context. In any case, NetLogo has plenty of
mathematical primitives that you should be able to use to arrive at the number you want.

Related

Introducing IDs to patches in Netlogo

I am working on a model which is supposed to act like a human tissue. It is composed of only patches which represent the human cells. The cells replicate over time, and I want to introduce unique IDs to each of the individual patches (cells). These IDs should also carry over to the daughter cells after the replication. I cannot seem to find a good starting point for this and not sure how to approach it.
This is the code I tried but it is not working to even at least give each patch a unique ID. Track clones is supposed to give each of the patches an ID and I will later introduce more to the code to track individual patches and their division over time.
to track-clones
; let patch-list patches
; let patch-count count patches
; foreach patch-list [
; set id ?1
; ]
end
This will have each patch take unique and sequential IDs:
to assign-ids
ask patches [
set id (max [id] of patches + 1)
]
end
That said, it is not clear to me what you mean, in model's terms, when you say
These IDs should also carry over to the daughter cells after the replication.
given that we don't know how such replication is supposed to take place - but it seems this is a separate issue to address.
PS: the syntax using ? for anonymous procedures is no longer accepted, make sure to check the latest NetLogo Dictionary.
You can quickly assign an initial ID based on the patch coordinates
Ask patches [ set patch-id (pxcor - min-pxcor ) + (pycor - min-pxcor) * world-width
]
Alternately, you can use the patch itself as the patch ID:
Ask patches [ set patch-id self ]
This might make other operations relating to the progenitor patch simpler.

Removing an agentset from another agentset (the agents from the first set which are also present in the second set)

in my netlogo code I have a network with companies (that is my breed). I want to ask the companies to share information with their neighbors and their neighbors and so on, this works (see code below, the agentsets are b, c and d).
However when I ask for information on the third level neighbors my agentset also includes the first level neighbors (obviously since it takes all neighbors into acount), so I want to remove these first level neighbors from the third level neighbors agentset. In the code this means I want to remove agents present in D which are also present in B
But I cant find the way to do it, other doesnt work since it is not the agent asking which has to be removed. And remove also doesnt seem to do the job. I also tried != not equal to the first level but this reports a true or false and I just want to remove these agents from the third level agentset so I dont double count them.
ask companies [
let i who
let b link-neighbors
ask b [ let c link-neighbors
ask c [ let d link-neighbors
ask companies with [who = i] [
set iburen [who] of b
set iiburen [who] of other c
set iiiburen [who] of d
]
]
]
]
can somebody help me with this?
I think what you want is the member? primitive. If D and B are agentsets, the following should give you the members of D that are not members of B.
let DminusB D with [not member? self B]
Many things to say here:
Charles' answer is technically correct.
If a and b are agentsets, a with [ not member? self b ] will give you agents from a that are not already in b.
But I think there are better ways to accomplish what you are trying to do. I will come back to that, but first, a general piece of advice:
Don't use who!
The who primitive has some (very few) legitimate usages, but it's mostly evil. It tends to lead to brittle, inefficient code. For example, when you do:
let i who
; ...
ask companies with [who = i] [ ... ]
NetLogo has to scan all companies to find the one with that specific who number.
NetLogo can store agent references directly. Use that instead! For example:
let this-company self
; ...
ask this-company [ ... ]
Especially don't use lists of who numbers!
NetLogo is adequate for manipulating lists, but its awesome for manipulating agentsets. If you do something like this:
set iburen [who] of b
set iiburen [who] of other c
set iiiburen [who] of d
You are forfeiting the power of agentsets. I don't know why you want to store the three different levels separately, but supposing it's OK to store all your neighbors together, you could do:
set my-neighbors other (turtle-set b c d)
The use of other will exclude the original company and turtle-set will make sure that each agent in the set is unique (as agentsets can only contain unique agents anyway).
If you really want three separate variables, use Charles' answer, but make sure to store agentsets, not lists of who numbers!
If you don't need separate variables, however, I think the best solution would be to:
Use nw:turtles-in-radius.
NetLogo's Networks extension has a primitive that does exactly what I think you want to do:
ask companies [ set my-neighbors nw:turtles-in-radius 3 ]
That's it.

Two Turtles Breeds _ one breed is the variable of the other?

I've got a doozy of a Netlogo question. If I have two different breeds of turtles, can the sum of a specified number of one breed's variables BE THE VARIABLE of the other breed?
Here is my train of thought. I’d like to model water usage of multiple households, but that water usage of a household needs to be dependent on a) the fixed values of the house (like water used by a faucet) * b) frequency of use of faucet by a person. With each household containing either 1 or more person (people) and that frequency of use can vary person to person.
The idea of using two turtle breeds would allow me to see how the decisions made by one breed affects the other.
Here is my pseudo code to help illustrate what I was thinking (not intended to be a working code)
globals []
breed [People person]
breed [Community household]
People-own [frequency]
Community-own [waterusefacuet HouseholdWaterUse]
;; =================================================================================================================
;; =================================================================================================================
to setup
clear-all
HouseholdCreation
PersonCreation
reset-ticks
end
to go
ask Community [WaterConsumption]
tick
end
;; =================================================================================================================
;; =================================================================================================================
to HouseholdCreation
ask patches [ sprout-Community n of 1 [
set size 1.0 set shape "square" set color blue
set waterusefacuet (1)
] ]
end
to PersonCreation
ask Community [ hatch-People 1 [
set size 0.5 set shape "circle" set color red
set frequency (1 + random 4)
]]
end
to WaterConsumption
Set HouseholdWaterUse (waterusefacuet * (frequency * # of people) )
end
Why not simply make each patch a household, have each patch have one or more turtles (persons), and then calculate household factors as patch factors? To define communities one could place patches into zones (e.g., if pxcor >= 5 and pxcor <=8 and pycor >=3 and pycor <= 6 set zone 1) <== not meant to be code, just the idea.
You could set patch size to make each patch small and specify a large zone of patches.
can the sum of a specified number of one breed's variables BE THE VARIABLE of the other breed?
Absolutely.
snipsnip for clarification : In my code here, I do not let the water use of people who live in a household BE the water use variable of that household. And generally I would recommend against a solution that lets the state of one (or more) agents be the state of another variable - unless there is a very good reason for it. Having states depend on each other is dangerous because you always have to make sure that you sync the values between agents. More importantly, it's often unnecessary. In my solution here, each person belongs to a household, and when that households calculates its total water use, it asks all its inhabitants to send them their use on that day, and then returns the sum of all those numbers. I hope that makes sense. If not, please do ask.
*< /snipsnip>
You need to use the of keyword though. of allows you direct access to variables from the context/perspective of one or more individual agent. So, let's say we have households and people, and people (because we all have different water use habits) have some frequency of water tap uses. In fact, we could have people draw the amount of water they use every day from a a normal distribution that is unique to them. Let's do that:
breed [people person]
breed [households household]
people-own [
mean-use-per-day ;; mean use per day
sd-use-per-day ;; standard dev per day
my-household ;; the household to which a person belongs
]
to setup
create-households 10 [
hatch-people random 4 + 1 [ ;; between 1 and 4 people in a household
set mean-use-per-day random 5 + 5 ;; mean 5-9
set sd-use-per-day random-float 3 ;; sd 0.00-2.99
set my-household myself ;; we set the person's household to the household that hatched them
]
]
to-report household-water-use ;; household reporter
report sum [random-normal mean-use-per-day sd-use-per-day] of people with [my-household = myself] ;; this creates a list of water uses based on the random use of each person in the household.
end
in order to run this code, you can simply call
show [household-water-use] of households
from the command center. This will give you a list of the water use of each household. Or if you want to just see the water use of one household on one random day, you can try
show [household-water-use] of one-of households

How to change a turtle's attribute if one of its links disappear?

In NetLogo: suppose the model has
a turtle (0) of breed A with undirected links with 3 turtles (1, 2 and 3) of breed B;
the turtle 0 has an attribute named "number-of-links" that equals 3.
Now, let one of the 3 neighbors of 0 dies..
How can I program turtle 0 to change its number-of-links automatically to 2?
If all you want is a way of keeping track of the number links, use count my-links instead of a custom variable.
In general, the least bug prone way of having a value update when the number of links changes is to compute that value when you need it. For number of links, this is simply count my-links. For more complicated things, wrap them in a reporter:
to-report energy-of-neighbors
report sum [ energy ] of link-neighbors
end
If this doesn't work for whatever reason (agents need to react to a link disappearing or you're seeing a serious, measurable performance hit from calculating on the fly), you'll have to make the updates yourself when the number of links change. The best way to do this is to encapsulate the behavior in a command:
to update-on-link-change [ link-being-removed ] ;; turtle procedure
; update stuff
end
and then encapsulate the things that can cause the number of links to change (such as turtle death) in commands as well:
to linked-agent-death ;; turtle procedure
ask links [
ask other-end [ update-on-link-change myself ]
]
die
end

How to avoid individual patch updates

I am modeling diffusion in my model, but I think I am getting a calculation artifact due to NetLogo sequentially updating individual patches. I will not be using the diffuse command (due to inaccurate diffusion). However, much like how this command works, I would like to update all the calculations of the patches simultaneously, rather than sequentially. I have a slight recollection of seeing some sample code that used values at the beginning of the tick, however I can´t seem to find it now.
Specifically, I need help programming a way to store patch values at the turn of each tick, and then carry out a simultaneous calculation based on these stored values.
Great question. As you indicate, basically you want to calculate the new value of the variable in one ask block, but store it in a separate variable, and then update the actual value of the variable in a second ask block, like so:
turtles-own [
value
new-value
]
...
to go
ask patches [
;; Change this line to however you want the diffusion to work
set new-value 0.5 * value + sum [ 0.5 * value / 4 ] of neighbors4
]
ask patches [
set value new-value
]
end
This way all patches calculate their updated values from the same information, and then actually update the values themselves simultaneously.