Ale
Ale

Reputation: 107

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

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.

Upvotes: 0

Views: 141

Answers (2)

Wade Schuette
Wade Schuette

Reputation: 1473

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

Upvotes: 1

Wade Schuette
Wade Schuette

Reputation: 1473

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 "

Upvotes: 0

Related Questions