NetLogo Sandpile模型 - 增强模型所需的代码

时间:2015-03-27 15:38:14

标签: performance netlogo

以下代码与NetLogo Sandpile模型有关,其中在每个时间步骤添加随机粒度的沙子。当沙粒数量超过阈值极限时,它将触发雪崩类型事件。

我现在想用进一步的代码来增强这个模型,以便在每次滴答时(在随机添加沙粒之前),代码现在执行以下规则:

(1)如果其8个邻居中的大多数是n> 1,则每个补丁计数将增加其计数(n + 1)。 1.

(2)如果其8个邻居中的大多数是n <1,则每个补丁计数将其计数减少到(n = 0)。 1.

然后将随后添加一粒沙子移至第二步,如下面的原始代码所示:


xtensions [sound]
globals [
  ;; By always keeping track of how much sand is on the table, we can compute the 
  ;; average number of grains per patch instantly, without having to count.
  total
  ;; We don't want the average monitor to updating wildly, so we only have it 
  ;; update every tick.
  total-on-tick
  ;; Keep track of avalanche sizes so we can histogram them
  sizes
  ;; Size of the most recent run
  last-size
  ;; Keep track of avalanche lifetimes so we can histogram them
  lifetimes
  ;; Lifetime of the most recent run
  last-lifetime
  ;; The patch the mouse hovers over while exploring
  selected-patch
  ;; These colors define how the patches look normally, after being fired, and in 
  ;; explore mode.
  default-color
  fired-color
  selected-color
  threshold-color


]

patches-own [
  ;; how many grains of sand are on this patch
  n
  ;; A list of stored n so that we can easily pop back to a previous state. See
  ;; the NETLOGO FEATURES section of the Info tab for a description of how stacks
  ;; work
  n-stack
  ;; Determines what color to scale when coloring the patch. 
  base-color
]

;; The input task says what each patch should do at setup time
;; to compute its initial value for n.  (See the Tasks section
;; of the Programming Guide for information on tasks.)
to setup [setup-task]
  clear-all

  set default-color blue
  set fired-color red
  set selected-color green

  set selected-patch nobody
  ask patches [
    set n runresult setup-task
    set n-stack []
    set base-color default-color
  ]
  let ignore stabilize false
  ask patches [ recolor ]
  set total sum [ n ] of patches
  ;; set this to the empty list so we can add items to it later
  set sizes []
  set lifetimes []
  reset-ticks
end

;; For example, "setup-uniform 2" gives every patch a task which reports 2.
to setup-uniform [initial]
  setup task [ initial ]
end

;; Every patch uses a task which reports a random value.
to setup-random
  setup task [ random error-count ]
end

;; patch procedure; the colors are like a stoplight
to recolor
   set threshold-color threshold + 2
   set pcolor scale-color base-color n 0 threshold-color
end

to go
   if ticks = time 
    [ sound:play-note "Trumpet" 60 64 2 stop ]
  let drop drop-patch
  if drop != nobody [
    ask drop [
      update-n 1
      recolor
    ]
    let results stabilize animate-avalanches?
    let avalanche-patches first results
    let lifetime last results

    ;; compute the size of the avalanche and throw it on the end of the sizes list
    if any? avalanche-patches [
      set sizes lput (count avalanche-patches) sizes
      set lifetimes lput lifetime lifetimes
    ]
    ;; Display the avalanche and guarantee that the border of the avalanche is updated
    ask avalanche-patches [ recolor ask neighbors4 [ recolor ] ]
    display
    ;; Erase the avalanche
    ask avalanche-patches [ set base-color default-color recolor ]
    ;; Updates the average monitor
    set total-on-tick total
    tick
  ]
end

to explore
  ifelse mouse-inside? [
    let p patch mouse-xcor mouse-ycor
    set selected-patch p
    ask patches [ push-n ]
    ask selected-patch [ update-n 1 ]
    let results stabilize false
    ask patches [ pop-n ]
    ask patches [ set base-color default-color recolor ]
    let avalanche-patches first results
    ask avalanche-patches [ set base-color selected-color recolor ]
    display
  ] [
    if selected-patch != nobody [
      set selected-patch nobody
      ask patches [ set base-color default-color recolor ]
    ]
  ] 
end

;; Stabilizes the sandpile. Reports which sites fired and how many iterations it took to
;; stabilize.
to-report stabilize [animate?]
  let active-patches patches with [ n > threshold ]


  ;; The number iterations the avalanche has gone for. Use to calculate lifetimes.
  let iters 0

  ;; we want to count how many patches became overloaded at some point
  ;; during the avalanche, and also flash those patches. so as we go, we'll
  ;; keep adding more patches to to this initially empty set.
  let avalanche-patches no-patches

  while [ any? active-patches ] [
    let overloaded-patches active-patches with [ n > threshold ]
    if any? overloaded-patches [
      set iters iters + 1

    ]
    ask overloaded-patches [
      set base-color fired-color
      ;; subtract 'threshold' amount from this patch
      update-n -4
      if animate? [ recolor ]
      ;; edge patches have less than four neighbors, so some sand may fall off the edge
      let selected-neighbors n-of 4 neighbors 
      ;; World is wrapped horizonatlly and vertically so we can always select 4 random neighbors.
      ;; However, we only want to select neighbors which are on the table.
      ;; That is what the next section of code does.
      set selected-neighbors selected-neighbors with [ 
        (abs (pxcor - [ pxcor ]  of myself) < 2) ;; selects patch < 2 from myself which is one patch away.
        and
        (abs (pycor - [ pycor ]  of myself) < 2)
        ] 
      ask selected-neighbors  [
        update-n 1
        if animate? [ recolor ]
      ]
    ]
    if animate? [ display ]
    ;; add the current round of overloaded patches to our record of the avalanche
    ;; the patch-set primitive combines agentsets, removing duplicates
    set avalanche-patches (patch-set avalanche-patches overloaded-patches)
    ;; find the set of patches which *might* be overloaded, so we will check
    ;; them the next time through the loop
    set active-patches patch-set [ neighbors ] of overloaded-patches
  ]
  report (list avalanche-patches iters)
end

;; patch procedure. input might be positive or negative, to add or subtract sand
to update-n [ how-much ]
  set n n + how-much
  set total total + how-much
end

to-report drop-patch
  if drop-location = "center" [ report patch 0 0 ]
  if drop-location = "random" [ report one-of patches ]
  if drop-location = "mouse-click" and mouse-down? [
    every 0.3 [ report patch mouse-xcor mouse-ycor ]
  ]
  report nobody
end

;; Save the patches state
to push-n ;; patch procedure
  set n-stack fput n n-stack
end

;; restore the patches state
to pop-n ;; patch procedure
  ; need to go through update-n to keep total statistic correct
  update-n ((first n-stack) - n)
  set n-stack but-last n-stack
end

0 个答案:

没有答案