So I am working on a project that requires me to divide subsidy over two different types of turtles. I got 1 port and 25 industries (so, two breeds) and need to divide 15M EUR subsidy between the two breeds. So far, when I set the slider of subsidy on 50/50 (50% for port and 50% for industries), I get that 7.5 M for the port and 7.5 M for each industry but I want each industry to have 7.5M / 25 EUR. How can I solve this? See the code below:
to distribute-subsidies
ask ports
[ set subsidy-port (subsidy-port + 150000 * subsidy-to-port) / count ports
]
ask industries
[ set subsidy-industry (subsidy-industry + ((15000000 - 150000 * subsidy-to-port) / count industries ))
]
end
All help is welcome! Thanks in advance.
Max
I think you need to be more clear with an example. Are you doing a 1-time transfer or every tick? I think it's clearer that you keep track of your subsidies to distribute in a variable. However, below I've provided an example to update the subsidies each tick and distribute the subsidies to both ports and industries, then within the ports and industries divide them amongst all the respective agents evenly.
to distribute-subsidies
let subsidies 1500000
ask ports
[ set subsidy-port subsidy-port + ((subsidies * subsidy-to-port) / count ports)
]
ask industries
[ set subsidy-industry ((subsidies * ( 1 - subsidy-to-port)/ count industries)
]
end
Related
I want to write in Netlogo that a certain percentage of the agent's population has this attribute. How do I do that in NetLogo?
So far, in a toy model, I do it manually. i.e: ask n-of 740 households [set composition 1] when in fact I want to say: ask 8% of the households to set composition 1.
There are two ways. I will call them ex-ante and ex-post.
Ex-ante
A frequent approach is to let each agent have a certain chance (expressed as the percentage value) of doing something. In this case you will use the random-float command in combination with your percentage value, which is the standard way to make things happen in NetLogo according to a certain probability (see here, or also see just random if you're working with integers). It can be used directly within the create-turtles block of commands:
globals [
the-percentage
]
turtles-own [
my-attribute
]
to setup
clear-all
set the-percentage 0.083 ; In this example we set the percentage to be 8.3%.
create-turtles 500 [
if (random-float 1 < the-percentage) [
set attribute 1
]
]
end
This means that you will not always have the exact number of turtles having that attribute. If you check count turtles with [attribute = 1] on multiple iterations, you will see that the number varies. This approach is good if you want to reproduce the probability of something happening (over a population of agents or over time), which is the case for many uses of NetLogo models.
Ex-post
The ex-post approach follows the logic that you more or less expressed: first you create a number of turtles, later you assign to them the attribute. In this case, you simply need to treat the percentage as in any other mathematical expression: multiply it by the total number of turtles to get the relevant turtles:
globals [
the-percentage
]
turtles-own [
my-attribute
]
to setup
clear-all
set the-percentage 0.083
create-turtles 500
ask n-of (count turtles * the-percentage) turtles [
set attribute 1
]
end
With this approach, you will always have the exact same number of turtles with that attribute. In fact, if you run count turtles with [attribute = 1] on multiple iterations you'll see that the result is always 41 (500 * 0.083 = 41.5, in fact if the number passed to n-of is fractional, it will be rounded down).
I would like to change the minimum coordinate unit of the patch space, which is set to exist only one turtle per patch space, to less than one, and monitor it. We want to set the minimum spatial unit to the same tick size n as in tick-advance (e.g. n=0.1). Here is a piece of code, but it doesn't work. Can anyone help me? Thanks in advance.
globals [n] ; n<=1 i.e. n=0.1
; omitted
ask turtles [forward n]
tick-advance n
I find myself in the same boat as Matteo- I don't know that what you're looking to do is possible / makes sense in the context of NetLogo. The coordinates of patches are fixed (ie, one patch is one unit) but arbitrary (1 in Netlogo can mean 1 m or 1 km, depending on the model). In other words, a patch's coordinates are discrete, while turtles can move around in continuous space. So you can, of course, have a turtle wander around in step sizes of 1/10:
globals [n]
to setup
ca
set n 0.1
crt 10
reset-ticks
end
to go
ask turtles [
forward n
]
tick-advance n
end
After one run of go above, you could conceivably have a turtle at coordinates [xcor = 0.1, ycor = 0.1], although it would still be on patch 0 0 since pxcor values are integers.
It seems that what you are actually needing to do is not coming across as needed- can you edit your question to provide a little more detail / context? Perhaps knowing the why behind your need to model in this way will help askers get you pointed in the right direction. I personally am curious about:
Why you are using tick-advance instead of just tick
How you have implemented your one-turtle-per-patch restrictions- in other words, can you show a Minimal Reproducible Example? That may prompt other ways to approach what you're after.
Here is an example world with time tied to ticks:
globals [ seconds ]
to setup
ca
set seconds 0
resize-world 0 50 0 50
ask patches with [
floor (pxcor / 10) mod 2 + floor (pycor / 10) mod 2 = 1
] [
set pcolor white
]
crt 10
reset-ticks
end
to go
ask turtles [
fd 1
]
set seconds precision (seconds + 0.1) 2
if seconds mod 1 = 0 [print ( word "It has been " seconds " seconds.")]
tick
end
I want to modell the interactions of different tree species in a forest. To do so, I also have to simulate the growth/spread of the forest.
There I face the two following problems:
I want the trees to reach a minimum age from which on they can hatch a new tree each year. But I only know how to make them reproduce every (e.g.) 20 years.
There is also a set age at which the trees are chopped town. The problem is, that when this age is reached, all trees of one breed are chopped down, even if their age should actually be less than their harvest-age.
Here are the relevant parts of my code:
to go
ask oaks [set age ticks]
end
to set-harvest-age
ask oaks [set harvest-age 240]
end
to spread
ask oaks [
if (age mod 30 = 0) and (count oaks > 1) [hatch-oaks 1 [setxy random-xcor random-ycor set age 1]]]
end
to chop-down
ask oaks [if (age >= harvest-age) [die]]
end
The "set age 1" in "spread" does not seem to work. Maybe someone of you has an idea.
Thank you!
I think your main problem is the process order here. Every time go is called, all oaks will set their age to the current ticks. That includes any new saplings that you've hatched, so even if their age was 1 when they hatched, those saplings would instantly be set to the same age as all other oaks (which is just the number of ticks. Instead, you should use your oaks-own (or whatever species you want) variable to track the age of each individual turtle by incrementing it every tick rather than setting it to the ticks.
Additionally, it's probably better to use go or a similarly named procedure to act as the scheduler to call all the other relevant procedures. For example, check out these setup chunks:
breed [ oaks oak ]
oaks-own [ age harvest-age ]
to setup
ca
spawn-oaks
reset-ticks
end
to spawn-oaks ; setup procedure
create-oaks 10 [
set shape "tree"
set color green
setxy random-xcor random-ycor
; Set the harvest age
set harvest-age 100
; Randomly choose the age of the first generation
; to be somewhere between 50 and 75
set age 50 + random 25
]
end
This creates 10 oaks with a an age randomly between 50 and 75. It also sets their harvest age. Now, use a procedure to increase every oak's individual age by one each tick:
to get-older ; Oak procedure
set age age + 1
end
Then, something to have them start creating saplings when they reach maturity. I've included an if any? other oaks-here qualifier so that the population size doesn't immediately explode (as saplings can only survive on a patch without an established oak), but you would limit that growth in whatever way makes sense for your model.
to spread ; Oak procedure
; Get living, mature oaks to spead saplings nearby
; only some years (to avoid population explosion)
if age > 30 and random 50 < 5 [
hatch 1 [
; set sapling age to zero, and have it
; move away from its parent randomly
set age 0
rt random 360
fd random 5
if any? other oaks-here [
die
]
]
]
end
Finally, your chop-down procedure should actually work without changing now that the age issue is sorted out:
to chop-down ; Oak procedure
if age >= harvest-age [
die
]
end
Now all that's needed is to use go to call those procedures in the correct order:
to go
; Use the go procedure to schedule subprocedures
ask oaks [
get-older
spread
chop-down
]
tick
end
Bit of a silly example but hopefully will get you pointed in the right direction!
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
I have 300 workers, and want to divide them into 3 sets of 100 (for now, eventually I will divide them perhaps unequally) based on two rankings. I have written variations to accomplish the following:
Select the top 100 on X, assign value 1 to variable A. Select the too 100 on Y (who have not ALREADY been assigned value 1 on A) and assign value 2 to variable A. Select remainder and assign value 3 to A
I have tried about a dozen approaches, without success. The closest I have come is to get the first 100. BUT, as there are ties, there are a few workers tied at the 100th-rank on X. Netlogo randomly selects one to receive value 1 on Variable A, which is fine. The problem is, because I haven't been able to figure out how to simultaneously construct three mutually exclusive agentsets using 2 criteria, I end up re-assigning workers from value 1 to value 2 on A. I can fix it by hand now, but eventually that won't be possible.
Here's the code that made the first value assignment:
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
The problem seems to be that I cannot figure a way to reference the top 100 on Y of the remaining 200. Nor can I reference the bottom 100 of the remaining 200, because it is possible for a worker to be in the Top 100 on X but NOT in the Top 100 on Y, in which case they'll (wrongly) fall into the sequentially-identified agentset unless I delete them from the operation. I've tried using member? and man other possibilities. Basically, I don't know how to simultaneously dump the first 100 of 300 and only "sort" the remaining 200 to make the assignment.
I've looked at multiple sources for an answer, so far to no avail. I've made a lot of progress on my code since Saturday, but this is a stumbling block.
Any assistance is greatly appreciated!
Thanks!
SLuke
RESOLVED! (YAY!)
In case anyone else has the problem, what I did is the following:
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
ask workers [ifelse AWeight = 1 [set LPMid2 -1000] [set LPMid2 LPMid]]
ask max-n-of 100 workers [LPMid2] [set MWeight 1]
ask workers [set PreWeight ( AWeight + MWeight )]
ask workers [if PreWeight = 0 [set RWeight 1]]
Note that LPMid2 sets the AWeight=1 to -1000, which is way out of range for the actual LPMid variable I later will need.
Sorry to bother the list; I hope the answer is of use to someone else should they have a similar problem.
here's a perhaps easier to read and more scaleable version (untested) of some of your code to hopefully give you some ideas about how to exclude some turtles when you are trying to select from a subset.
ask max-n-of 100 workers [LPAdv] [set AWeight 1]
ask max-n-of 100 workers with [AWeight != 1] [LPMid2] [set MWeight 2]
Also, you don't need two ask statements at the and (and asking twice is less efficient):
ask workers
[ set PreWeight ( AWeight + MWeight )
if PreWeight = 0 [set RWeight 1]
]