1

I'm working on a smaller project and got stuck on an issue, I'm not really sure if it's possible to solve it in NetLogo but I want to give StackOverflow a go!

I got a model that divides the world into different parts and randomly add physical features (such as rivers). If a feature goes through the whole region, I want it to separate the region and make into two regions. As an example, in the picture below, I want to separate the purple region into two unique regions accordingly to the physical feature (black).

1

The code I used to generate the picture above, can be found below.

to setup
  ca

  ;Setting world.
  resize-world 0 19 0 19

  ;Creating regions. 
  let x 5
  let y 5
  let col 45
  while [y <= max-pycor + 1][
    while [x <= max-pxcor + 1 ][
      ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
        set pcolor col
      ]
      set x x + 5
      set col col + 10
    ]
    set x 5
    set y y + 5
  ]

  ;Generating physical features.    
  ask n-of 5 patches[ sprout 1[
    set pcolor black]
  ]

  let i 0
  while [ i < (max-pycor * 2 )][
    ask turtles [
      fd 1
      set pcolor black
      ifelse (random 20 <= 1)
      [
        rt one-of [-90 0 90]      
        forward 1
      ]
            [
        fd 1
        set pcolor black
        fd 1
        set pcolor black
      ]
      set pcolor black
      set i i + 1]
  ]

  ask turtles [die]
end 
desertnaut
  • 57,590
  • 26
  • 140
  • 166
ecl
  • 369
  • 1
  • 15

2 Answers2

1

My strategy for handling this is to realize that all we really need to do is "flood" a patch out by color and tag all the found adjacent patches, then repeat for any un-tagged, non-black patches until they are all done.

NetLogo does not have a "flood" command to get all patches adjacent to a patch meeting a criteria, so we make a special reporter of our own to handle it, patches-adjacent. Then it's just easy to ask those patches-adjacent to set their region to the currently chosen region.

I don't love this code, it's a little finicky and would be prone to infinite loops if tweaked incorrectly, but it should work. I bet there is a cleaner way to do this that I'm not thinking of at the moment.

; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]

to set-regions 
  let current-region 1
  ; only act on non-black patches that haven't yet been assigned a region
  let untagged patches with [ region = 0 and pcolor != black ]
  while [any? untagged] [
    ask one-of untagged [
      ask patches-adjacent [
        set region current-region 
      ]
    ]
    ; update the region and the untagged patches we have left to process
    set current-region current-region + 1 
    set untagged patches with [ region = 0 and pcolor != black ]
  ]
  ; this is just to get a view of the regions to quickly see if our code worked, it can be removed
  ask patches [ set plabel region ]
end

to-report patches-adjacent
  report patches-adjacent-ex (patch-set self) pcolor
end

to-report patches-adjacent-ex [found pc]
  let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
  set found (patch-set found newly-found)
  ask newly-found [
    ; use recursion to find the patches adjacent to each newly-found one
    ; relying on updating the `found` agentset as we go to avoid duplicates
    ; or looping forwarder
    set found (patches-adjacent-ex found pc) 
  ]
  report found
end
desertnaut
  • 57,590
  • 26
  • 140
  • 166
Jasper
  • 2,610
  • 14
  • 19
  • 2
    same approach, maybe also try the Patch Clusters model in the NetLogo model library – JenB Mar 11 '20 at 20:31
  • Thank you so much, @Jasper, looks very promising. However, I'm having some issues understanding your code and it yields an error. In the very end, the following line of code **"set found (patches-adjacent-ex found)"** gives me the following error: **"PATCHES-ADJACENT-EX expected 2 inputs"** Which is the second input I'm expected to add? – ecl Mar 11 '20 at 21:01
  • @JenB Thank you, got it to work with the Patch Cluster model. – ecl Mar 11 '20 at 21:13
0

I solved this by using the Patch Clusters model that can be found in the NetLogo model library.

ecl
  • 369
  • 1
  • 15