Multi-scale landscape in Netlogo (small patches and larger patch groupings) - netlogo

I am trying to represent a multi-scale environment where I have large patches that represent high-value areas in the landscape and smaller patches that have local information. E.g. I want to have snow data at a 1km^2 scale but I also want to have larger patches (9km^2) that summarize large-scale information. Each of my large patches has a variable value that is different from its neighbors but the variable value may be repeated throughout the landscape in other patches. I am looking for the most straightforward way for my turtles to identify the difference between the large-scale patches. I had thought of creating patch-sets but I am not sure how to get around the issue of variable values repeating in different patches. Any help is much appreciated.
EDIT: I have created a raster with equal patch structure as the large-scale raster and assigned "patch-id's" using this, so that there is no longer variable repetition in the world. I am still struggling with getting turtles to identify these larger patches as grouped entities.

You commented on my first answer
My main issue is that I need to run a "find max-one-of
neigboring-large-patches [large-scale-variable]" so I need my turtles
to understand what the neighboring large-patches are and be able to
read them as units, if that makes sense. I can't quite figure out how
to incorporate that into your answer, any thoughts?
Here's how to do that. This code is fast and sloppy but it illustrates the point.
Let the large-regions have x and y values, generated during creation. Basically, these store the column and row numbers of the grid of large regions that covers the viewport.
breed [ large-regions large-region ]
large-regions-own [
terrain
region-color
population
x
y
]
Then, conceptually, the neighbors of a region will have x and y values within +/- 1 of the region's x and y values, so you can identify them that way.
To simplify coding at the expense of space, when I generated the regions I also stored the unique identifier (who) of that region and its x and y values into every patch in that region, in variables lrx and lry.
patches-own [
large-region-who
lrx
lry
]
The heart of finding the neighboring large-region with the max value of population as you requested follows. I coded this for speed in debugging , not for elegance, so it can be greatly cleaned up. The full source code has many print statements that effectively comment each step in solving your requested search.
This looks around (patch 0 0), finds the info on the large region's x and y from that patch, generates an agent-set of large-regions with nearby x and y values, does a max [population] search on that set to extract the region with the highest population. It also colors the asking patch black, the local large-region blue, and the maximum population neighbor red.
It mostly works -- the large regions are offset by one patch from where they should be -- but this illustrates the point. Run setup and go and see for yourself.
Here's the (ugly) code to play with. Interesting problem. You can easily extend this to small regions as well, and have both working at the same time. Enjoy!
globals [
large-region-size
]
breed [ large-regions large-region ]
large-regions-own [
terrain
region-color
population
x
y
]
patches-own [
large-region-who
lrx
lry
]
to setup
clear-all
set large-region-size 5
no-display
make-large-regions
ask patches [ set pcolor white ]
display
ask large-regions [ set hidden? true]
print (word " hilly region count: " count large-regions with [terrain = "hilly"] )
;; print (word " deep snow count: " count small-regions with [snow-cover > 75])
reset-ticks
end
to go
ask patches [ set pcolor white]
; ;; lets examine the large-regions
; print " large region xvals "
; let xvals [ ]
; ask large-regions [ set xvals fput x xvals ]
; set xvals remove-duplicates xvals
; show xvals
; print " "
; print " patch lrx values: "
; set xvals [ ]
; ask patches [ set xvals fput lrx xvals ]
; set xvals remove-duplicates xvals
; show xvals
; print "========================================="
print " let's examine large-regions around the patch at 0 0 "
let x-spot 0
let y-spot 0
print ( word " looking for large-regions with max population bordering the following patch " x-spot " " y-spot)
; ask n-of 1 patches [ set x-spot pxcor set y-spot pycor print (word "selected patch " x-spot ", " y-spot )]
let home-who [ large-region-who] of patch x-spot y-spot
print (word "home-region-who is " home-who)
print " "
;; thinking ahead, we have coded the x and y values of the large region around us directly into the patch variables
let home-x [ lrx ] of patch x-spot y-spot
let home-y [ lry ] of patch x-spot y-spot
print (word "this blue home region has x=" home-x " and y=" home-y )
ask patches with [lrx = home-x and lry = home-y] [ set pcolor blue ]
ask patch x-spot y-spot [ set pcolor black ]
let home-neighbor-set large-regions with [
( x >= ( home-x - 1 )) and ( x <= ( home-x + 1) ) and (y >= ( home-y - 1 ) ) and ( y <= ( home-y + 1 ) ) ]
print "count of home-neighbor-set is "
print count large-regions with [
( x >= ( home-x - 1 )) and ( x <= ( home-x + 1) ) and (y >= ( home-y - 1 ) ) and ( y <= ( home-y + 1) ) ]
print " "
print "here is that set "
show home-neighbor-set
print " "
ask home-neighbor-set [ print (word "Large region with who = " who " has population " population )]
let big-boy max-one-of home-neighbor-set [ population]
show big-boy
print ( word " Neighboring red large-region with largest population is " big-boy " with population " [population] of big-boy )
let bbx 0
let bby 0
let bwho 0
ask big-boy [ set bbx x set bby y set bwho who]
ask patches with [lrx = bbx and lry = bby] [ set pcolor red ]
tick
end
to make-large-regions ;; for testing
let px min-pxcor
let py min-pycor
let region-id -1 ;; missing
let mysize large-region-size
let stopper 0
while [px < max-pxcor] [
while [py < max-pycor] [
if stopper > 300 [ stop ] ;; stops making large regions
set stopper stopper + 1
let xcode round ( ( px + 1) / 5)
let ycode round ( ( py + 1) / 5)
;; make a new region
let decolor one-of [ red blue yellow green ]
create-large-regions 1 [
set terrain one-of ["hilly" "flat" "mountain" "water" "swamp"]
set region-id who
set population random 1000
set x xcode
set y ycode
set region-color decolor
]
;; large region is defined, update the patches in that region
ask patches with [ (abs (pxcor - px) < (mysize / 2) )
and (abs (pycor - py) < (mysize / 2) )] [
set pcolor decolor
set large-region-who region-id
set lrx xcode
set lry ycode
]
set py py + mysize
]
if py > max-pycor [
set py min-pycor
set px px + mysize]
]
end

This may not be the best way, but I think it would work. You could let regions own several variables, such as "large-region-unique-id" and "small-region-unique-id" and make one pass where you set all these variables. Then a turtle would only have to look at a patch to know what small and large region it is part of.
If you also made a breed of agents called "regions" (say), you could have regions-own variables and have a unique-region-id. ( actually, the agent's who number would work
for that)
That should encode the information so that a moving turtle could easily look up relevant information.
breed [ large-regions large-region ]
large-regions-own [
terrain-type
large-scale-variables
...
(who)
]
breed [ small-regions small-region ]
small-regions-own [
snow-cover
small-scale-variables
...
(who)
]
patches-own [
large-scale-region-who ;; the id (who) of the large-scale-region the patch is in
small-scale-region-who ;; the id (who) of the small-scale-region the patch is in
...
]
Then a turtle could ask a patch for the relevant who information and use it to look up data from the larger "patches".
Here's what that might look like
print (word " hilly region count: " count large-regions with [terrain = "hilly"] )
print (word " deep snow count: " count small-regions with [snow-cover > 75])
;; how about highlighting patches that are mountainous with deep snow?
no-display
ask patches [
set terrain-type ""
set my-snow-cover -1
set srw small-scale-region-who
if srw > 0 [set my-snow-cover [snow-cover] of (small-region srw)]
set lrw large-scale-region-who
if lrw > 0
[ set terrain-type [terrain] of large-region lrw]
if-else (terrain-type = "mountain") and (my-snow-cover > 75)
[ set pcolor white ]
[ set pcolor black ]
]
display
print " The mountainous terrain with deep snow-cover is shown in white "

Related

Cannot find item in list based on index in NetLogo

im using a sorted list in netlogos but when i run my code i get an error message that it can't find element 3 because the lenght of the list is 3, that sounds really strange and counter intuative to me. what goes wrong
globals [
allehøjder
min_højde
nedre_højde
median_højde
øvre_højde
max_højde
]
breed [personer en_person]
personer-own [højde skostørrelse]
to setup ; runs when the button "setup" is pressed
clear-all
;kom alle højder ind i højde
;sorter højde listen
;find 5 kvartil værdien ud fra højder[]
create-personer 3
[
set color white
set højde (150 + ( random ( 190 - 150 )))
set skostørrelse (38 + (random ( 47 - 38 )) )
setxy random-xcor random-ycor
set size 10
]
set allehøjder [højde] of personer
set alleskostørrelser [skostørrelse] of personer
show sort allehøjder
show sort alleskostørrelser
;sætter de 5 kvartilværdier for højde
; sætter min
set min_højde item 1 (sort allehøjder)
;sætter max
**bold** set max_højde item 3 (sort allehøjder)
; sætter median
ifelse 3 mod 2 = 0
;lige antal
[
set median_højde item ((3 + 1 / 2) ) (sort allehøjder)
]
;ulige antal
[
set median_højde ((item ((3 + 1) / 2) (sort allehøjder) + item (((3 + 1) / 2) + 1) (sort allehøjder)) / 2)
]
reset-ticks
end
regards morten
The indexing of lists' items starts from 0, hence the third element will have index 2.
The NetLogo Programming Guide and the NetLogo Dictionary linked above should have you covered with this type of problems.

why the error you can not use it as an observer context showed up?

I need your support as I'm using the (interact) command as a button it it gives me an error ( you can not use it as an observer context), as I need to make interaction in area = 1 among agents.the setup button as I defined 5 areas with agents with different colors, and I want them to move to area = 1 and interact as per their culture features
This is the code
breed [ parents parent ]
breed [ childrens children ]
patches-own [ area]
turtles-own [ my_area culture ]
to setup
ca
define_areas
create_parent
create_children
ask turtles [ set culture [] ]
ask turtles [ set my_area [area] of patch-here ]
repeat cultural_features
[ ask turtles [ set culture fput ( random traits_per_feature + 1 ) culture ] ]
reset-ticks
end
to define_areas
ask patches with [ (pxcor > -3) and (pxcor < 3) and (pycor > -3) and (pycor < 3) ] [ set pcolor white set area 1 ]
ask patches with [ (pxcor > 5 ) and (pxcor < 16 ) and (pycor > 4) and (pycor < 16) ] [ set pcolor white set area 2 ]
ask patches with [ (pxcor < -5 ) and (pxcor > -16 ) and (pycor > 4) and (pycor < 16) ] [ set pcolor white set area 3 ]
ask patches with [ (pxcor < -5 ) and (pxcor > -16 ) and (pycor < -4) and (pycor > -16) ] [ set pcolor white set area 4 ]
ask patches with [ (pxcor > 5 ) and (pxcor < 16 ) and (pycor < -4) and (pycor > -16) ] [ set pcolor white set area 5 ]
end
to create_parent
ask n-of Population patches with [ ( area = 2 ) ] [ sprout 1 [ set shape "person" set color green set size 1.5 ] ]
ask n-of Population patches with [ ( area = 3 ) ] [ sprout 1 [ set shape "person" set color red set size 1.5 ] ]
ask n-of Population patches with [ ( area = 4 ) ] [ sprout 1 [ set shape "person" set color blue set size 1.5 ] ]
ask n-of Population patches with [ ( area = 5 ) ] [ sprout 1 [ set shape "person" set color grey set size 1.5 ] ]
end
to create_children
ask n-of ( kids * ( Population / 2 ) ) patches with [ ( area = 2 ) ] [ sprout 1 [ set shape "person" set color green set size .5 ] ]
ask n-of ( kids * ( Population / 2 ) ) patches with [ ( area = 3 ) ] [ sprout 1 [ set shape "person" set color red set size .5 ] ]
ask n-of ( kids * ( Population / 2 ) ) patches with [ ( area = 4 ) ] [ sprout 1 [ set shape "person" set color blue set size .5 ] ]
ask n-of ( kids * ( Population / 2 ) ) patches with [ ( area = 5 ) ] [ sprout 1 [ set shape "person" set color grey set size .5 ] ]
end
to move_in_event
ask n-of random ( (count turtles with [ size = .5 ]) / 2 ) turtles with [ size = .5 ]
[ move-to one-of patches with [ (not any? other turtles-here) and ( area = 1 ) ] ]
end
to interact
; identifing the agent chosen
let selected_agent one-of turtles with [ area = 1 ]
print ( word "selected agent="" " selected_agent)
;; culture of selected_agent
let my_culture culture
print ( word "selected agent culture ="" "my_culture)
;; the agent chooses one neighbor
let chosen one-of neighbors with [ area = 1 ]
print ( word "chosen agent ="" "chosen)
;; identify the culture of her neighbor
let chosen_culture [culture] of chosen
print ( word "chosen agent culture ="" "chosen_culture)
; Creating a local variable to track the number of similarities between the
;agents and calculate the probabilities of interactions between two agents
let similarities 0
let position_different_traits []
; create a list from 0 to number of cultural features
let N_traits n-values cultural_features [ i -> i ]
print ( word "Number of traits to be compared ="" "N_traits)
; For each traits of the cultural features
foreach N_traits
[ i -> ifelse ( (item i my_culture) = (item i chosen_culture ))
[ set similarities similarities + 1 ]
[ set position_different_traits lput i position_different_traits ] ]
;; print out some information to check how does the procedure performs
print ( word "position_different_traits ="" "position_different_traits)
print ( word "number of similarities ="" "similarities)
; Calculate probability
let p ( similarities / cultural_features) * 100
print ( word "probability ="" "p)
; Calculate a random number between 1 & 100
let dice random 100 + 1
print ( word "Roll a die ="" "dice)
if (dice <= p)
[
ifelse(similarities != cultural_features)
[
let position_ one-of position_different_traits
print ( word "position_trait_to_be_changed in the agent="" "position_)
let replacement_item item position_ chosen_culture
print ( word "element to from chosen agent to be replaced in active agent culture="" "replacement_item)
set culture replace-item position_ culture replacement_item
print ( word "active agent culture updated ="" "culture)
]
[
]
]
; only for visualization purposes
ask selected_agent [ set color [ color ] of chosen]
ask chosen [ set color [ color ] of selected_agent ]
end
You are using the button to run the interact procedure. Here is the beginning of that procedure with comments and printing deleted.
to interact
let selected_agent one-of turtles with [ area = 1 ]
let my_culture culture
The first thing this procedure does is randomly select a turtle and give it the label 'selected_agent'. Then the next line says let my_culture culture but it doesn't say which agent's value of the variable 'culture' to use. Since 'culture' is an agent variable, the only way this line makes sense if it runs from the context of the agent, but you are running from the context of the observer. That's why you get the error.
The way to fix it is to specify which agent's value of culture you want to assign.
let my_culture [culture] of selected_agent

Netlogo, creating breed at the center of a particular polygon (i.e with id = 123456)

I have a netlogo gis model. the gis shape file consists of building footprint (in the form of polygons). I want to create a breed at the center of particular building with id = "66445345" (polygon id). There is large no of buildings/ polygons but I am only interested in creating the breed at this one polygon
Any ideas how to do this?
breed [blds bld]
set guo-building gis:load-dataset "guo-building.shp"
gis:drawing-color gray
gis:draw guo-buildings 1.0
foreach gis:vertex-list-of guo-buildings[
i ->
let bld-no gis:property-value i "id"
let center gis:centroid-of i
let center-location gis:location-of center
if bld-no = 66445345
[create-blds 1
[
set xcor (item 0 center-location)
set ycor (item 1 center-location)
set color red
set size 5
]
]
]
sorted the problem. Need insert blds-own variable and store id.
breeds [blds bld]
breeds-own [building-no]
to setup-pma-locations
foreach gis:feature-list-of guo-buildings[
i ->
let bld-no gis:property-value i "ID"
let center gis:centroid-of i
let center-coordinates gis:location-of center
if not empty? center-coordinates [
create-blds 1
[
set xcor (item 0 center-coordinates)
set ycor (item 1 center-coordinates)
set color red
set size 0
set building-no bld-no ;store in blds-own variable
]
]
]
ask blds[
let pma blds with [building-no = "66445345"]
ask pma [set color red
set size 5]
]

Efficient CSV extraction and allocation

I've tried to find a way to do this more neat/more efficient cause I don't believe that I wouldn't be able to achieve the same result more efficient.
I have a csv file containing data with initial states for my turtles. Each row represents values for turtle-owned variables and each column represents an individual turtle. For each turtle, I would like to initialize his variables. At this moment I'm doing it the following way (which works, but to me looks not efficient):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GENERAL PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
extensions [ csv ]
breed[households household]
globals ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[
HH-data
HHx-list
HHy-list
HHsize-list
HHcolor-list
]
households-own ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[
HHx
HHy
HHsize
Hhcolor
]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SETUP PROCEDURES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to startup ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
set HH-data (csv:from-file "TestHH.csv" ";")
show HH-data
set HHx-list item 0 HH-data
set HHy-list item 1 HH-data
set HHsize-list item 2 HH-data
set HHcolor-list item 3 HH-data
show HHx-list
let numberOfHH length HHx-list
create-households numberOfHH
(
foreach (sort households) HHx-list
[ [?1 ?2] -> ask ?1
[
set xcor ?2
]
]
)
(
foreach (sort households) HHy-list
[ [?1 ?2] -> ask ?1
[
set ycor ?2
]
]
)
(
foreach (sort households) HHsize-list
[ [?1 ?2] -> ask ?1
[
set HHsize ?2
]
]
)
(
foreach (sort households) HHcolor-list
[ [?1 ?2] -> ask ?1
[
set color ?2
]
]
)
end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
However, in the global HH-data already all my data is present. How could I extract this and assign the turtle variables to each turtle without having to make all these individual for-each statements. I tried a few things like this:
set HH-data (csv:from-file "TestHH.csv" ";")
show HH-data
let numberOfHH length (item 0 HH-data)
create-households numberOfHH
(
foreach (sort households) HH-data
[[?1 ?2] -> ask ?1
[
set xcor ?2
set ycor ?2
set HHsize ?2
set HHcolor ?2
]
]
)
But then I keep getting errors.
Found out myself, while I was writing this question, how to solve it.
Thought it might be useful to others and thus therefore to still post it.
set HH-data (csv:from-file "TestHH.csv" ";")
;;show HH-data
let numberOfHH length (item 0 HH-data)
create-households numberOfHH
(
foreach (sort households) (item 0 HH-data) (item 1 HH-data) (item 2 HH-data) (item 3 HH-data)
[[?1 ?2 ?3 ?4 ?5] -> ask ?1
[
set xcor ?2
set ycor ?3
set HHsize ?4
set color ?5
]
]
)

Changing range of variables netlogo

I have a variable:
ask group [set means-one groupmeans + resources-agent ]
I want to ask netlogo to constrain the variable between 1 to 99.
How?
Just to simplify Alan's first answer to remove the if statements:
You could do:
ask group [set means-one (max (list 1 (min (list 99 groupmeans + resources-agent))) ]
Your question is not entirely clear. What do you mean by "change the range"? If you mean to clip extreme values, you can do it like this:
to-report clip [#x #min #max]
if (#x < #min) [report #min]
if (#x > #max) [report #max]
report #x
end
Then you can ask turtles [set means-one clip means-one 1 99]. Otoh, if you actually want to rescale all existing values linearly into your new range, you could do the following:
to rescale-all-means-one
let _newmin 1
let _newmax 99
let _newrange (_newmax - _newmin)
let _lst [means-one] of turtles
let _min min _lst
let _max max _lst
let _range (_max - _min)
ask turtles [
let _scale (means-one - _min) / _range
let _scaled (_newmin + _scale * _newrange)
set means-one _scaled
]
end