以下代码与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