Storing a value - netlogo

A classroom is simulated where appliances (e.g lights Fans and ACs) turn on when a student sits next to it. Each appliance has its own wattage rating. When an appliance is turned on its color changes to green and the on-time is noted and the duration on-time is stored. But if a student sits next to a appliance (e.g light) that is already on. The duration-on-time should not be stored as it would be a repetition.
globals[
simulation-timer
to appliance-on
ask students [ ask lights in-radius 4
[ifelse not already-on?
[ set color green
set light-on-time ticks
set light-on-duration light-on-duration + (time - ticks)
show (word "light on duration = " light-on-duration)
set already-on? true] [
set light-on-duration light-on-duration]]]
In this code the light-on-duration is not adding for all of the lights. Only individual light-on-duration is shown. How should I fix this? Thank you!

I think you have a logic problem rather than a coding problem. You can't add to duration when the light turns on because it hasn't yet built up any duration. Here is a complete model that turns lights on and off and stores duration. I am using ticks as the time, and each tick it adds 5 students and removes 5 students. But what's important is the logic of turning the lights on and off.
globals [light-radius]
breed [students student]
students-own
[ desk
]
breed [lights light]
lights-own
[ on?
turned-on
duration-on
]
to setup
clear-all
set light-radius 3
ask patches [ set pcolor white ]
ask patches with [pxcor mod 3 = 0 and pycor mod 3 = 0]
[ sprout-lights 1
[ set size 0
set on? false
set pcolor gray
]
]
reset-ticks
ask n-of 30 patches
[ sprout-students 1
[ set color blue
]
ask lights in-radius light-radius [switch-light-on]
]
end
to go
repeat 5 [student-arrive]
repeat 5 [student-leave]
ask lights with [any? students in-radius light-radius]
[ switch-light-on
]
tick
end
to student-arrive
ask one-of patches with [not any? students-here]
[ sprout-students 1
[ set color blue
ask lights in-radius light-radius with [not on?]
[ switch-light-on
]
]
]
end
to switch-light-on
set pcolor yellow
set on? true
set turned-on ticks
end
to student-leave
ask one-of students
[ die
]
ask lights with [ on? and not any? students in-radius light-radius ]
[ switch-light-off
]
end
to switch-light-off
set pcolor gray
set on? false
type "previous duration: " print duration-on
let how-long ticks + 1 - turned-on
set duration-on duration-on + how-long
type "new duration: " print duration-on
end
Note that you can't actually see the light turtles, I am making the patch turn yellow for on and grey for off. Every third patch has a light.

Related

Stopping turtles from having negative resources

My model creates a relationship between employees and citizens. Whereby the employees obtain office and then distribute to the employees:
globals [
office-space
]
breed [ offices office ]
breed [ service-desks service-desk ]
breed [ employees employee ]
breed [ citizens citizen ]
offices-own [ money ]
employees-own [ money ]
citizens-own [ money ]
to setup
clear-all
create-offices 1 [
set shape "building institution"
set size 4
set color yellow
set money num-of-money
]
create-employees num-of-employees [
set shape "person"
set size 1.5
set color blue
setxy random-xcor random-ycor
]
create-citizens num-of-citizens [
set shape "person"
set size 1.5
set color white
setxy random-xcor random-ycor
]
;; create 4 service desks
let service-desk-patches (patch-set patch 0 8 patch 8 0 patch 0 -8 patch -8 0)
ask service-desk-patches [
sprout-service-desks 1 [
set shape "building institution"
set color pink
set size 3
]
]
;; create office space
set office-space patches with [pxcor <= 8 and pxcor >= -8 and pycor <= 8 and pycor >= -8 ]
ask office-space [set pcolor grey]
;; set all employees randomly within the grey box
place-on-color-employees
;; set all citizens randomly outside of the grey box
place-on-color-citizens
reset-ticks
end
to place-on-color-employees
let _patches (patches with [pcolor = grey])
ask employees [
move-to one-of (_patches with [not any? turtles-here])
]
end
to place-on-color-citizens
let _patches (patches with [pcolor = black])
ask citizens [
move-to one-of (_patches with [not any? turtles-here])
]
end
to go
ask employees [
set label money
]
ask citizens [
set label money
]
employee-movement-without-money
employee-take-money
employee-movement-with-money
citizens-movement
citizen-take-money
tick
end
to employee-movement-with-money
ask employees [
ifelse [ pcolor ] of patch-ahead 1 = black
[ rt random-float 360 ]
[ forward 1 ]
let target min-one-of citizens [ distance myself ]
if money > 0 [
face target
fd 1
]
]
end
to employee-movement-without-money
ask employees [
let target patch 0 0
if ( money = 0 ) or ( money < 0 ) [
face target
fd 1
]
]
end
to citizens-movement
ask citizens [
ifelse [pcolor] of patch-ahead 1 = grey
[ rt random-float 360 ]
[ forward 1 ]
let target min-one-of service-desks [ distance myself ]
if money = 0 [
set heading (towards target )
]
]
end
to employee-take-money
ask employees [
if any? offices-here [
set money money + 1
set color green
;set label money
]
]
end
to citizen-take-money
ask citizens [
if any? employees in-radius 0.5 [
ask employees [
set money money - 1
]
]
set money money + 1
set color orange
]
end
When this model is run, the employees collect money and go to meet citizens, however, in the citizen-take-money procedure, I have not found a way to prevent the citizens from taking money from the employees so they don't have negative values. I tried adding the employee-movement-without-money to force the employees to turn move away from the citizens, but they just congregate on patch 0 0.
I also tried adjusting the citizens-take-money procedures by creating an if and arugment:
to citizen-take-money
ask citizens [
if (any? employees in-radius 0.5) and (employees money > 0) [
ask employees [
set money money - 1
]
]
set money money + 1
set color orange
]
end
But that didn't work either.
First piece of advice, build NetLogo models gradually. You need to make sure each piece works before adding the slightly more complicated behaviour. You should never have more than one thing wrong in a NetLogo model at the same time, very hard to debug.
Here, the basic problem appears to be that you are acting on all turtles instead of just the relevant turtle. Here is your supplementary code that tries to introduce a check:
to citizen-take-money
ask citizens [
if (any? employees in-radius 0.5) and (employees money > 0) [
ask employees [
set money money - 1
]
]
set money money + 1
set color orange
]
end
First, have a look at your check - conceptually, what are you testing with the second part employees money > 0. That doesn't actually look like valid NetLogo code to me, are you trying to ask if there are any employees with with money > 0?
Regardless, let's say it gets past that check, the next line is ask employees - at this point you are telling EVERY employee in the model to reduce their money.
What you need to do is just find the right employees and have those ones reduce their money. Something more like:
to citizen-take-money
ask citizens
[ let nearby employees in-radius 0.5 with [money > 0]
if any? nearby
[ ask nearby [ set money money - 1 ]
set money money + 1
set color orange
]
]
end
Also, this procedure is asking every citizen to do this and you have named it as if only one citizen is doing it. So think about which way you actually want the process to work.
Finally, what happens if you have several citizens close to several employees. Say 3 citizens reduce their money because they are close to the same employee - at the moment, the employee only increases their money by 1 and the remaining 2 disappears. This is an example of what I mean by build gradually and check it works before adding in the next thing. Perhaps you could have them just change colours if the condition is met before trying to add in the money transfers. That would help you spot that you had lots of people triggered at once.

To do a netlogo model with several patch layers (think floors of a building) do I need to go to Netlogo 3D?

I have a netlogo application in mind which involves multiple non interacting layers. Think floors of a building. Would I need to go to netlogo 3D or is there a suggested way to handle in regular netlogo?
This was an interesting enough question that I decided to make a simple sample.
The method I use is to have a global variable to track the number-of-floors we'll have in our building, as well as the active-floor that we are currently working with. Then all our agents, walls and workers, have a floor-num that tracks which they are on. We have a set-active-floor procedure that handles switching our currently active floor that we want to see and work with, making the patches a certain color (active-color) if they have a wall agent present and swapping which workers are hidden?. In this way, most of the magic happens in the setup-floor and set-active-floor procedures, and the real work of our model in go can be pretty typical NetLogo code asking the active-workers to do whatever we want.
While the model is running you can call set-active-floor n to any value 0 to 4 to change the current workers and walls. I also included a show-all procedure that'll un-hide all the walls and workers and let you see where they are at; you'll need to run that with the model stopped.
globals [colors active-color number-of-floors active-floor]
turtles-own [floor-num]
breed [walls wall]
breed [workers worker]
to setup
clear-all
set colors (list red blue green orange violet)
set number-of-floors 5
foreach (range 0 number-of-floors) setup-floor
reset-ticks
set-active-floor 0
end
to setup-floor [num]
set active-floor num
set active-color (item num colors)
ask patches [ set pcolor black ]
; make some random walls
create-walls (count patches * 0.2) [
set floor-num num
set hidden? true
set size 0.5
setxy random-pxcor random-pycor
set pcolor active-color
]
; only one wall per patch
ask patches [
let patch-walls floor-walls-here
let wall-count count patch-walls
if (wall-count > 1) [
ask n-of (wall-count - 1) patch-walls [ die ]
]
]
; make some workes
create-workers 10 [
set floor-num num
set hidden? true
set shape "person"
set color active-color - 2
move-to one-of patches with [pcolor != active-color]
]
end
to go
; this only "runs" the active floor, but you could run all of them
; using the same `foreach (range 0 number-of-floors) ...` code as
; in the `setup` procedure.
set-active-floor active-floor
ask active-workers [
; this code can be about the same as you'd write in a normal model...
move-to one-of patches with [pcolor != active-color]
]
tick
end
to set-active-floor [num]
set active-floor num
set active-color (item num colors)
; after the `pcolor` is set, we can use that to determine if a wall
; exists or not for an `active-worker`, we don't have to check the
; floor number at all while we do our work.
ask walls [ set hidden? true ]
ask patches [
set pcolor ifelse-value no-walls-here [ black ] [ active-color ]
]
ask workers [
set hidden? floor-num != active-floor
]
end
to-report active-workers
report workers with [floor-num = active-floor]
end
to-report floor-walls-here
report walls-here with [floor-num = active-floor]
end
to-report no-walls-here
report (count floor-walls-here = 0)
end
to show-all
foreach (range 0 number-of-floors) [ num ->
ask patches [
set pcolor ifelse-value any? walls-here [ red - 3 ] [ black ]
]
ask turtles with [floor-num = num] [
set color item num colors
set hidden? false
]
]
end
Finally, if things got much more complicated than this, I would probably choose to move to NetLogo 3D instead.

"Can't use XXX in an observer context because patch only"

I am havig some diffuculties with a part of my code. Netlogo reort "Can't use GO in an observer context because patch only"
My guess is that this is because in the go part I ask for a procedure (CACULATEWILANDATRAC) that does not begin with "ask Patches". However the (CACULATEWILANDATRAC) produce is to calculate one of the patches own-variables, so ask patches does not seem fit here.
I still tried to solve it with putting ask patches before the procure but then
I get another error when running the model : " only the observer can ASK the set of all patches.
error while patch 1079 509 running ASK
called by (anonymous command: [ [the-Land-use the-Senario] -> ask patches [ if count patches with [ the-Land-use ] > the-Senario [ set Willingstochange True ] ] ]) called by procedure CACULATEWILANDATRAC"
The problem thus lies with where to call for the CACULATEWILANDATRAC procedure?
It is now part of the go procedure but this thus gives the error "Can't use XXX in an observer context because turtle only".
My entire code:
> extensions [gis]
globals
[
land-use-map
Senario1N ;; the count of patches senario 1 describes
Senario1L
Senario1A
Senario1B
Senario1I
Senario1R
Senario1W
%landusetypeN ;; the amount patches
%landusetypeL
%landusetypeA
%landusetypeB
%landusetypeI
Willingstochange ;; If true a patch would like to change (if true the count of patches has a surplus comparing to the sneario, if false they have a shortage)
atractiveness ;; if a patch type is attractive to change in <1 = yess
Atractiveneighbor
]
patches-own
[ Land-use ;; Wat kind og landusetype a patch has
]
to setup
clear-all
load-gis ;;load the maps
setup-constants
update-global-variables
update-display
reset-ticks
end
to load-gis ;;load the maps
set land-use-map gis:load-dataset "a_LANDUSE_cellsize5.asc" ;;loads the land use map
gis:set-world-envelope-ds gis:envelope-of land-use-map ;;sets the envelope of the world to match that of the GIS dataset
gis:apply-raster land-use-map Land-use ;;patches in the land-use-map have a specific land-use now
ask patches [
if Land-use = 1 [ set pcolor Green ] ; Green = Nature ;; patches have a certain color now
if Land-use = 2 [ set pcolor red ] ; Dark red = Leisure
if Land-use = 3 [ set pcolor Yellow ] ; Yellow = Agriculture
if Land-use = 4 [ set pcolor brown ] ; brouwn = Buildup
if Land-use = 5 [ set pcolor grey ] ; grey = roads
if Land-use = 6 [ set pcolor pink ] ; pink = industry
if Land-use = 7 [ set pcolor blue ] ; Blue = water
]
resize-world 0 1633 0 780
set-patch-size 1
end
to setup-constants
set Senario1N 49174 ;; the count of patches senario 1 describes
set Senario1L 17871
set Senario1A 569970
set Senario1B 34202
set Senario1I 5540
set Senario1R 34968
set Senario1W 65594
end
to go ;; this asks the model to caculate certain variables defined below
givecountlansusetypes
askforchange
caculateWILandAtrac
tick
end
to givecountlansusetypes ;; here the cuurent amount of patches is shown
show count patches with [Land-use = 1]
show count patches with [Land-use = 2]
show count patches with [Land-use = 3]
show count patches with [Land-use = 4]
show count patches with [Land-use = 5]
show count patches with [Land-use = 6]
show count patches with [Land-use = 7]
end
to update-display
ask patches
[
if Land-use = 1 [ set pcolor Green ] ;; Green = Nature ;; patches have a certain color now
if Land-use = 2 [ set pcolor red ] ;; Dark red = Leisure
if Land-use = 3 [ set pcolor yellow ] ;; Yellow = Agriculture
if Land-use = 4 [ set pcolor brown ] ;; brouwn = Buildup
if Land-use = 5 [ set pcolor grey ] ;; grey = roads
if Land-use = 6 [ set pcolor pink ] ;; pink = industry
if Land-use = 7 [ set pcolor blue ] ;; Blue = water
]
end
to update-global-variables
if count patches > 0
[ set %landusetypeN (count patches with [ Land-use = 1 ] / count patches) * 100
set %landusetypeL (count patches with [ Land-use = 2 ] / count patches) * 100
set %landusetypeA (count patches with [ Land-use = 3 ] / count patches) * 100
set %landusetypeB (count patches with [ Land-use = 4 ] / count patches) * 100
set %landusetypeI (count patches with [ Land-use = 6 ] / count patches) * 100
]
end
to caculateWILandAtrac
;; Sets Willingness to change true if patches are with more fellowpatches than the senario decribes
(foreach list (Land-use = 1) (Land-use = 2)[49174 17871]
[ [the-Land-use the-Senario] -> ask patches [if count patches with [the-Land-use] > the-Senario [ set Willingstochange True ] ] ])
;; gives score to the patches attractiveness based on the ratio patches/senario
(foreach list (Land-use = 1) (Land-use = 2)[49174 17871]
[ [the-Land-use the-Senario] -> ask patches [ set atractiveness (count patches with [the-Land-use]/ the-Senario) ] ])
end
to askforchange
ask patches [
if Willingstochange = true [change] ;; this ask the patches that are willing to change (have a surpuls) to go and change
]
end
to change
ask neighbors with [Willingstochange = false ] ;; this asks if the patch had neigbors with a shortage
[set Atractiveneighbor min-one-of patches [atractiveness]] ;; this asks to give the neigbor with the lowest patchcount/senario ratio
ask patches [set Land-use ([Land-use] of Atractiveneighbor)] ;; this asks the patches to change their land-use to the land-use of neigbor with the lowest patchcount/senario ratio
end
In your last line of code the current asked patch (asked in askforchange) asks all patches to set their Land-use accordingly. I think that there lies your problem.
Maybe it solves your problem, if you replace the last line with the following:
set Land-use ([Land-use] of Atractiveneighbor)
With this, the currently asked patch changes its land-use accordingly. But I am not quite sure, if that is what you want the procedure to do there?

Netlogo: how can I use contract net protocol in my model

Good morning people,
At the moment I have a template in netlogo that allows to visualize routes of deliveries in houses created randomly.
globals[route-vector]
breed [carr car]
breed [spare spares]
breed [hous housess]
breed [spawns spawn]
carr-own [ route route-counter spawn-target target route-complete?]
spare-own[ route route-counter spawn-target target route-complete?]
to setup
clear-all
create-carros
create-casas
path
reset-ticks
end
to create-carros
create-carr 2 [ set color green ]
ask carr [
set size 1.5
setxy random-xcor random-ycor
set route-counter 0
set target nobody
set route []
set route-complete? false
pd
]
end
to create-carspare
create-spare 1 [ set color blue ]
ask spare [
set size 1.5
setxy random-xcor random-ycor
set route-counter 0
set target nobody
set route []
set route-complete? false
pd
]
end
to create-casas
create-hous 5 [ set color red ]
ask hous [
set shape "house"
set size 1.5
setxy random-xcor random-ycor
]
end
to path
set route-vector [4 7 6 3 5 0 1 1 0 1]
let houses sublist route-vector 0 (length route-vector / 2 )
let carlist sublist route-vector (length route-vector / 2 ) (length route-
vector)
(foreach carlist houses
[ [the-car the-house] ->
ask car the-car [
set route lput ( housess the-house ) route
]
]
)
ask carr [
hatch 1 [
set breed spawns
ht
]
set spawn-target one-of other turtles-here with [
xcor = [xcor] of myself
]
]
end
to go
ask carr with [ not route-complete? ] [
if route = [] [
set target spawn-target
]
if target = nobody [
set target item route-counter route
]
face target
ifelse distance target > 1 [
fd 1
] [
move-to target
ifelse target != spawn-target [
set route-counter route-counter + 1
] [
set route-complete? true
]
set target nobody
]
if route-counter > length route - 1 [
set route-counter 0
set target spawn-target
]
]
tick
end
I thought about using a broken or crash switch, and a slider with how many maximum home deliveries per car.
in my go procedure I put:
ask carr with [failure?] [
if ticks = 25 [ask one-of carr [set crash? TRUE]
set target spawn-target
Assuming the maximum deliveries per car are 3 and as one or more houses will not be visited because of the car that stopped, I put a reschedule button:
to reschedule
ask one-of spare with [not route-complete?] ; How do I make the reservation
car take the route of the car that stopped?
[
set target [car route that stopped]
]
set target spawn-target
end
I need some help in my reschedule bottom. if a car stops, and does not finish the route, the reserve car should take over the houses that are missing to visit
Thanks in advance for your understanding, and if you can help, I was grateful.
If I understand what you are asking, you have a car that has crashed and want to pass on the content of one of its variables to the spare car. The car that is crashed has the variable crash? set to TRUE, but I can't see from your code how you define a car to be the spare car. But it's probably something like this.
ask cars
[ <doing whatever they do>
if <conditions for crash>
[ set crash? TRUE
ask one-of cars with [spare?]
[ set spare? FALSE
set target [target] of myself
]
stop
]
]

Preferential attachment: Selecting a node to attach

I've been struggling with this one for the last 24 hours or so I feel like I'm missing something relatively simple here.
to setup-scale-free-network
clear-all
;; Make a circle of turtles
set num-nodes (num-children + num-adults + num-toddlers)
create-children num-children
create-adults num-adults
create-toddlers num-toddlers
layout-circle turtles (max-pxcor - 8)
ask turtles[
create-links-with turtles with [self > myself and random-float 5 < probability]
]
setup
end
to-report find-partner
report [one-of both-ends] of one-of links
end
The above code creates a set number of turtles of various breeds and creates a number of links between these breeds.
to go
reset-ticks
make-link find-partner
tick
end
The two procedures would be called until the needed level of degree distribution as been met.
What I want to do is use the find-partner procedure to move towards preferential attachment to do this I need to modify this code to create a link from the node find partner has selected to one of each of the other three types of breeds in my network.
to make-node [old-node]
crt 1
[
set color red
if old-node != nobody
[ create-link-with old-node [ set color green ]
;; position the new node near its partner
move-to old-node
fd 8
]
]
end
My own attempts have lead no where to be honest. I know I'm asking for a lot of help but I'm at my wits end here, thank you for your help and patience.
I was unable to completely understand your question. I am guessing that you wish to create another type of link which you call preferential attachment (with green color) between turtles who are already a part of the network.
One thing you might want in this situation is that you do not pick turtles which are already in a preferential attachment network. [this is just my assumption]
I have modified your code (as follows) to get the desired network with preferential attachment shown with green colored links, have added a turtle-variable already-attached which is used to exclude turtles which are already preferentially attached to others.
Hope this helps!
breed [ children child ]
breed [ adults adult ]
breed [ toddlers toddler ]
children-own [ already-attached ]
adults-own [ already-attached ]
toddlers-own [ already-attached ]
to setup-scale-free-network
clear-all
let num-children 5
let num-adults 5
let num-toddlers 5
let probability 1
;; Make a circle of turtles
create-children num-children [ set color orange ]
create-adults num-adults [ set color green ]
create-toddlers num-toddlers [ set color blue ]
layout-circle turtles (max-pxcor - 8)
ask turtles
[
create-links-with turtles with [self > myself and random-float 5 < probability]
]
end
to go
setup-scale-free-network
ask turtles with [already-attached = 0]
[
attach-to-one-of-each-breed self
]
end
to attach-to-one-of-each-breed [ source-node ]
ask source-node
[
if any? other children with [ already-attached = 0 ]
[
ask one-of other children
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
if any? other adults with [ already-attached = 0 ]
[
ask one-of other adults
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
if any? other toddlers with [ already-attached = 0 ]
[
ask one-of other toddlers
[
set already-attached 1
create-link-with source-node [ set color green ]
]
]
]
end