Modified Random Clusters

Modified Random Clusters preview image

1 collaborator

Jm1_vsm James Millington (Author)

Tags

clustering 

Tagged by Reuven M. Lerner over 4 years ago

landscape 

Tagged by Reuven M. Lerner over 4 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.0.1 • Viewed 569 times • Downloaded 35 times • Run 0 times
Download the 'Modified Random Clusters' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


## WHAT IS IT?

A implementation of the modified random clusters method for landscape pattern simulation described by Saura and Martinez-Millan (2000) and implemented in SIMMAP (http://www2.montes.upm.es/personales/saura/software.html#simmap). Used previously in Millington et al. (2008, http://jasss.soc.surrey.ac.uk/11/4/4.html)

## HOW IT WORKS

Follows the Steps A-D described in Saura and Martinez-Millan (2000, p.664-665)

## HOW TO USE IT

Select the number of land cover (or habitat, etc.) types to be generated in the map. Select the cluster-probability to determine amount of clustering. Select whether von Neumann or Moore neighbourhood rule should be used. Click 'generate-landscape' button. Once landscape pattern is generated the map can be exported to ESRI ascii grid format by clicking "export-map".

## THINGS TO TRY

Examine how the size and number of patches produced varies for different values of number-of-types, cluster-probability and neighbourhood type.

## EXTENDING THE MODEL

Feel free to use the code in your own models.

## RELATED MODELS

Similar code used in Millington, J.D.A., Romero-Calcerrada, R., Wainwright, J. and Perry, G.L.W. (2008) An agent-based model of Mediterranean agricultural land-use/cover change for examining wildfire risk Journal of Artificial Societies and Social Simulation 11(4) 4 http://jasss.soc.surrey.ac.uk/11/4/4.html

## CREDITS AND REFERENCES

Modified random clusters method described in: Landscape patterns simulation with a modified random clusters method, Santiago Saura and Javier Mart�nez-Mill�n (2000) Landscape Ecology 15 661-678 http://dx.doi.org/10.1023/A:1008107902848

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  Modified random clusters method for landscape pattern simulation - NetLogo  ;;
;;                                                                              ;;
;;  Code licenced by James D.A. Millington (http://www.landscapemodelling.net)  ;;
;;  under a Creative Commons Attribution-Noncommercial-Share Alike 3.0          ;;
;;  Unported License (see http://creativecommons.org/licenses/by-nc-sa/3.0/)    ;;
;;                                                                              ;;
;;  This code is based on the method by Saura & Martinez-Millan (2000)          ;;
;;  Landscape Ecology 15 661-678 http://dx.doi.org/10.1023/A:1008107902848      ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  


patches-own 
[ 
  cover        ;; cover of patch
  cluster_ID   ;; id of cluster patch belongs to
  cluster      ;; holds a patch which is that cluster's "leader" - arbitrarily chosen
]


globals 
[ 
  cluster-area-list  ;for plotting purposes
]




;---------------

to generate-landscape

  set cluster-area-list []
  
  set_random_seeds                                 ;; randomly distribute cluster seeds (Step 1 in Saura & Martinez-Millan 2000 p.664)

  set-cover                                        ;; identify and label clusters (Steps 2 & 3 in above)
  fill_landscape                                   ;; fill remaining patches to dominant neighbour (Step 4 in above)
  
  ask patches [ set pcolor (cover * 10) + 5 ]      ;; color patches according to cover types

  plotting                                         ;; plot bar plots
end 
;---------------




;---------------

to set-cover
  loop
  [ 
    let seed one-of patches with [ ( cluster = nobody and pcolor = blue ) ]   ;; pick a random seed we haven't labelled yet
    if seed = nobody                                                          ;; if we have labelled all seeds stop
      [ stop ]
      
    ask seed                   
    [                          
      set cluster self                     ;; make the seed the "leader" of a new cluster by assigning itself to its own cluster
      set cover ( random Number-of-Types )       ;; assign this "leader" a random cover      
      grow-cover_cluster                   ;; then grow-cover_cluster to find the rest of the cluster     
      
      set cluster-area-list fput count patches with [cluster = myself] cluster-area-list        
    ]
    
  ]   
end   
;---------------




;---------------      

to grow-cover_cluster               
  
  without-interruption              ;; we use without-interruption here so each patch only gets added to the cluster once
  [ 
    let neighbours nobody
    
    ifelse(Neighbourhood = "Moore") 
    [ set neighbours neighbors with [ cluster = nobody and pcolor = [pcolor] of myself ] ]
    [ set neighbours neighbors4 with [ cluster = nobody and pcolor = [pcolor] of myself ] ]
    
    ask neighbours
    [ 
      set cluster [cluster] of myself    ;;assign neighbouring patch to seed patch cluster
      set cover [cover] of myself        ;;assign neighbouring patch to seed patch cover
      set cluster_ID [cluster_ID] of myself
      grow-cover_cluster                 ;;recursive call!
    ] 
   ]
end 
;---------------





;---------------

to set_random_seeds
  
  let cluster-counter 0
  
  ask patches 
  [
    set cover nobody                  
    set cluster_ID nobody                 
    set cluster nobody                    
  ]
  
  ask patches 
  [  
    ifelse ( (random-float 1) < cluster-probability )  ;set patch as seed if rand no is less than cluster_probability
    [ 
      set pcolor blue                                ;seeds are blue
      set cluster_ID cluster-counter 
      set cluster-counter cluster-counter + 1
    ]                            
    [ set pcolor red ]                               ;non-seeds are red
  ]
end 
;---------------



;---------------

to fill_landscape                  ;; assign patches not initially assigned (to dominant cover in neighbourhood)
  
  loop 
  [
    if ( not any? patches with [ cluster = nobody ] )     ;;if all patches have been assigned to an cover-cluster 
    [ stop ]
 
    ask one-of patches with [ cluster = nobody ]  ;;pick a patch that has not been assigned to an cover-cluster yet
    [
      let neighbours nobody
  
      ifelse(Neighbourhood = "Moore") 
      [ set neighbours neighbors ]
      [ set neighbours neighbors4 ]
        
      
      ifelse ( any? neighbours with [ cluster != nobody ] )  ;; check if there are any assigned patches in neighbourhood
      [ 
        
        let covers []
        
        ask neighbours with [ cluster != nobody ] 
        [
          set covers fput cover covers    ;;ask neighbours to add their covers to the list
        ] 
          
        let unique-covers remove-duplicates covers    ;;create a list of unique covers
                                      
        let max-cover-count -1                 ;the number of neighbours with the maximum cover
        let max-cover -1                       ;the maximum cover
        
        
        ifelse(length unique-covers > 1)
        [
          ;if there is more than one unique-cover
          foreach unique-covers                  ;for each of the unique covers
          [
            let occ occurrences ? covers          ;count how many neighbours had this cover
            
            ifelse(occ > max-cover-count)        ;if the count is greater than the current maximum count
            [ 
              set max-cover ?                    ;set this as the dominant cover
              set max-cover-count occ            ;update the current maximum count
            ]
            [
              if(occ = max-cover-count)          ;otherwise, if the count is equal to the current maximum count
              [
                let rand random-float 1          
                if(rand < 0.5) [ set max-cover ? ]  ;randomly pick one of the two covers to be the new dominant cover
              ]
            ]
          ]
        ]
        
        [
          ;otherwise just set the max-cover to the only unique-cover
          set max-cover first unique-covers
        ]
 
  
        let p one-of neighbours with [ cover = max-cover ]    ;;assign qualities of one of dominant neighbours to patch (no wrap!)
        set pcolor [pcolor] of p 
        set cluster [cluster] of p   
        set cover [cover] of p 
        set cluster_id [cluster_id] of p
      ]
      [                                                               ;; if no assigned agents in neighbourhood assign an agent at random
        set cover ( random Number-of-Types) 
        set cluster self                                              ;; remember to start a new cluster!
        set cluster_ID ([cluster_ID] of max-one-of patches [cluster_ID]) + 1
      ]
    ]
  ]
end 
;---------------





;; count the number of occurrences of an item in a list
;---------------

to-report occurrences [x the-list]
  report reduce
    [ifelse-value (?2 = x) [?1 + 1] [?1]] (fput 0 the-list)
end 
;---------------



;---------------

to plotting
  
  set-current-plot "Cluster-Distribution"
  clear-plot
  histogram cluster-area-list
  
  set-current-plot "Cover-By-Area"
  clear-plot
  let cover-counts []
  let c 0
  while[c < Number-of-Types] 
  [ 
    set cover-counts fput 0 cover-counts 
    set c c + 1
  ]
  ask patches [ set cover-counts replace-item cover cover-counts ((item cover cover-counts) + 1) ]
  
  set c 0
  while[c < Number-of-Types]
  [
    plotxy c item c cover-counts
    set c c + 1
  ]
  
  
  
  set-current-plot "Count-Clusters-By-Cover"
  clear-plot
   
  set cover-counts []
  set c 0
  while[c < Number-of-Types] 
  [ 
    set cover-counts fput 0 cover-counts 
    set c c + 1
  ]
  
  let max-cluster-ID 0
  ask max-one-of patches [cluster_ID][ set max-cluster-ID cluster_ID ]
  
  let id 0
  while[id <= max-cluster-ID] 
  [
    let p one-of patches with [cluster_ID = id]
    
    if(p != nobody)
    [
      ask p
      [
        set cover-counts replace-item cover cover-counts ((item cover cover-counts) + 1) 
      ]
    ]
    set id id + 1
  ]
  
  print cover-counts
  
  set c 0
  while[c < Number-of-Types]
  [
    plotxy c item c cover-counts
    set c c + 1
  ]
end   
;---------------



;---------------

to export-map
  
  file-close-all 
  if(file-exists? "export.asc") [file-delete "export.asc"]
  file-open "export.asc"
  
  
  file-type "ncols   " 
  file-print world-width
  file-type "nrows   "
  file-print world-height 
  file-print "xllcorner  0" 
  file-print "yllcorner  0" 
  file-print "cellsize   1" 
  file-print "NODATA_value  -9999"
  
  let x min-pxcor
  let y max-pycor
  
  while[y >= min-pycor]
  [
    while[x <= max-pxcor]
    [
      ifelse(x = max-pxcor)
      [
        ask patches with [pxcor = x and pycor = y] [ file-print cover ]
      ]
      [
        ask patches with [pxcor = x and pycor = y] [ file-type cover file-type " "]
      ]
      
      set x x + 1
    ]
    
    set x min-pxcor
    set y y - 1
  ]
  
  file-close
end 
;---------------

There is only one version of this model, created over 4 years ago by James Millington.

Attached files

File Type Description Last updated
Modified Random Clusters.png preview Preview for 'Modified Random Clusters' over 4 years ago, by James Millington Download

This model does not have any ancestors.

This model does not have any descendants.