如何在 NetLogo 6.2 中创建顺序计数器?

How to create a sequential counter in NetLogo 6.2?

我想知道是否有任何方法可以在不使用间隔列表的情况下实现顺序计数器。我正在尝试执行以下操作:在每个滴答结束时计算人口规模 (NFinal)。然后,我们将通过减法检查人口的稳定性(逻辑测试是这种减法的结果在连续 3 个滴答期间等于零?)。

For example:

NFinal of tick 0 - NFinal of tick 1 = 0
NFinal of tick 1 - NFinal of tick 2 = 0
NFinal of tick 2 - NFinal of tick 3 = 0

If this is the scenario (with 3 sequential values ​​equal to zero), the simulation will stop.

However, if it is in the scenario:

NFinal of tick 0 - NFinal of tick 1 = 0
NFinal of tick 1 - NFinal of tick 2 = 0
NFinal of tick 2 - NFinal of tick 3 = 2

The simulation does not stop (since it did not have 3 zero values ​​in sequence) and therefore would reset the counter to continue the simulation.

然而,我设法实现的是使用列表的间隔。我不知道这是不是最好的方法。好吧,每次我使用列表时,我的模型都会变慢。有没有更简单的方法来实现这个?

提前致谢!

下面的尝试:

globals [ StabilityList ConstanceInterval ]

to go
  if ConstanceInterval = 0 [ stop ]
end
  
to StabilityCheckerProc  
  set StabilityList lput 1 StabilityList  ;; 1 = NFinal
  let i 3 ;; 
  if length StabilityList >= i
  [
    let t1 last StabilityList    
    let start ( length StabilityList - i ) 
    let t0 item start StabilityList
    set ConstanceInterval abs ( t1 - t0 )       
  ] 
  set StabilityList get-last i StabilityList 
end

to-report get-last [ num lst ]
  let b length lst
  let a b - num
  report sublist lst ( ifelse-value ( a < 0 ) [ 0 ] [ a ] ) b
end

您可以使用计数器来跟踪连续出现的次数,这样,如果您的条件得到满足,则增加计数器,如果不满足,则重置计数器。例如:

globals [ zero-tracker ]

to setup
  ca
  reset-ticks
end

to go 
  let variable-placeholder random 5
  ifelse variable-placeholder = 0 [
    ; If a zero is recorded (eg, the result of your subtraction operation, 
    ; increase the zero-tracker by one
    set zero-tracker zero-tracker + 1
  ]  [
    ; If anything BUT a zero is recorded, reset the zero-tracker
    set zero-tracker 0
  ]
  tick
  if zero-tracker = 3 [
    stop
  ]
end

卢克的回答就是答案。

但是,如果出于任何原因你确实遇到了需要查看最后 X 件事的问题,并且计数器不起作用,你可以使用列表,但保持长度为 X。

;; in setup, initialize the list with 'memory-size' items
set memory map [ -> 0] range 0 memory-size

;; in go, add a new memory to the list, and drop an old memory
set memory but-first lput value memory

;; then do what you must to examine the memories
< that code here >

仍然比使用计数器慢,但可能比从 ever-growing 个值列表中累加和提取部分要快。

如果您确实需要维护 ever-growing 个值列表,您可能仍会维护这个较小的列表。

最后,即使使用 ever-growing 值列表,将子列表从列表前面移除的操作也会更少:

;; add new memory to front of list
set memory fput value memory 
;; get last three memories from front of list
let last-three sublist memory 0 3 ;; no math or length needed

一如既往,测试任何可能更快的断言。