Netlogo:减去先前扩散的值

Netlogo: subtracting previously diffused values

是否可以减去之前扩散的值?

我有一个土地利用模型,其中住宅用途(黄色斑块)通过扩散基元扩散其土地价值:

diffuse land-value 1

在下图第一张图中,土地价值以白色调表示,色调越亮,土地价值越高。住宅用途有时会放弃补丁,但他们的土地价值影响仍然存在(第二张图片)。有没有一种方法,当土地利用消失时,它之前扩散到所有斑块的价值被减去并消失?

根据问题下的评论并根据 Luke 关于将 land-value 的扩散定义为距离的函数而不是重复出现的 diffuse 的建议,我制定了以下解决方案(在第 1 点中).

在下面(第 2 点),如果您想坚持 diffuse

,您会找到解决问题的可能方法(未完全编码,但已勾勒出足够的草图)

1 - 具有距离函数的方法

这里发生的事情是,当一个斑块获得住宅地位(to create-residence)时,一定半径内的所有其他斑块根据该斑块的住宅价值计算他们获得多少溢出土地价值新住宅区及其距离 (to-report diffused-value)。

这种方法的优点是这种计算在任何时候都是完全可复制的,因为它基于两个常数:补丁之间的距离和相关补丁的初始住宅值(我为此创建了补丁-自己的own-residential-value,区别于一般的land-value).

因此,当一个补丁失去住宅用途 (to dismantle-residence) 时,可以执行相同的计算,但不是让补丁将 diffused-value 添加到它们的 land-value,他们会减去它。

如果您在界面中创建 create-residencedismantle-residence 按钮,我认为我放在下面的代码最能说明其功能,并使用它们来查看重叠的土地价值如何加减在视图中。

globals [
 ; Agentsets for patches.
 residence
 non-residence
]

patches-own [
  land-value
  own-residential-value
]

to setup
  clear-all
  set non-residence (patch-set patches)
  set residence (patch-set)
end

to create-residence
  let new-res one-of non-residence

  ask new-res [
   set non-residence (patch-set other non-residence)
   set residence (patch-set self residence)

   set own-residential-value (random 10) + 1
   set land-value (land-value + own-residential-value)
   set pcolor yellow

   diffuse-value
  ]

  update-colours
end

to diffuse-value
  ask other patches in-radius 10 [
   set land-value (land-value + diffused-value)
  ]
end

to dismantle-residence
  let target one-of residence

  ask target [
   set residence (patch-set other residence)
   set non-residence (patch-set self non-residence)

   ; As opposed to 'to create-residence', where 'diffuse-value' is at the end of this block of commands,
   ; here 'subtract-value' has to be placed before the patch updates its 'own-residential-value' to 0,
   ; because that value is needed to calculate 'diffused-value'.
   subtract-value

   set land-value (land-value - own-residential-value)
   set own-residential-value 0
  ]

  update-colours
end

to subtract-value
  ask other patches in-radius 10 [
   set land-value (land-value - diffused-value)
  ]
end

to-report diffused-value
  ; Here, 'myself' is the new residential patch (as 'new-res' in 'to create-residence') or
  ; the new non-residential patch (as 'target' in 'to dismantle-residence').
  let d distance myself
  let v [own-residential-value] of myself

  report v * (0.9 / d) ; Just an arbitrary function of value and distance.
end

to update-colours
  ask non-residence [
    set pcolor scale-color white land-value 0 15
  ]
end

2 - 如果坚持 diffuse

我也有针对这种情况的方法,但我也想了解 diffuse 是否真的是您想要使用的方法。

据我们所知,diffuse是一个zero-sum game:一个补丁扩散的东西也被一个补丁丢失了。

因此,我想你不会只使用 diffuse land-value 1,因为在那种情况下,住宅补丁的 land-value 将在一个 tick 后为 0,在随后的 tick 上会非常轻微地恢复,然后从第三个刻度开始逐渐接近 0。

例如,下面的代码给出如下table中的结果:

patches-own [
  land-value
]

to setup
  clear-all
  reset-ticks
  
  ask patch 0 0 [set land-value 50]
end

to go
  diffuse land-value 1
  tick
end

我怀疑这是您有兴趣复制的任何东西,所以我假设该方法类似于:

patches-own [
  land-value
  temp
]

to setup
  clear-all
  reset-ticks
  
  ask patch 0 0 [set land-value 50]
end

to go
  diffuse-value
  tick
end

to diffuse-value
  ask patches [
   set temp land-value 
  ]
  
  diffuse land-value 1
  
  ask patches [
   set land-value (land-value + temp) 
  ]
end

但是,我认为即使在这种情况下 diffuse 似乎也不适合代表传播到附近地区的住宅价值。通过上面的代码,其实结果是这样的:

上面的table显示,在15个刻度内,应该是在该区域扩散一些值的补丁经历了93593%的增长(不,我没有忘记任何小数点!)在它的土地价值。我当然知道这可能会通过一些公式来缓解,但我认为它显示了 diffuse 倾向 在这种情况下:在补丁之间创建不断升级的正反馈,以便一个小的住宅价值不受控制地增长。

我不是这里的住宅价值专家,但我觉得这些结果(来自 diffuse 的前者和后者的使用)从 NetLogo 的角度来看值得指出。

说的就是,如果想法是坚持diffuse...

patches-own [
 land-value
 own-residential-value
 residential-start
 temp
]

to setup
 ; Some code.
end

to go
 ; Some code.
end


to create-residence   ; Executed by the observer. This procedure cannot be executed by the patch becoming residence because it contains 'diffuse'.
 
 let target ; <- Identify here the patch that needs to become residence.
 
 ask target [
  ; Set 'own-residential-value' to something.
  set land-value (land-value + own-residential-value)
  set residential-start ticks
 ]

 ; Have some code here that uses 'diffuse own-residential-value'.

end


to dismantle-residence   ; Executed by the observer. This procedure cannot be executed by the patch being dismantled because it contains 'diffuse'.

 ask patches [set temp 0] ; This is crucial in order to avoid any overlap among patches when using 'diffuse'.
 
 let target ; <- Identify here the patch that needs to be dismantled.
 let time-as-residence (ticks - [residential-start] of target)
  
 ask target [
   set temp own-residential-value 
  ]
  
 repeat time-as-residence [
  ; Insert here the exact same code that
  ; was used for using 'diffuse' but
  ; diffusing the 'temp' variable instead
  ; (e.g. 'diffuse temp 1').
 ]

 ask patches with [temp > 0] [
  set land-value (land-value - temp)
 ]
end

上面发生的事情是,每当补丁失去住宅用途时,程序执行的 diffuse 操作与在补丁的居住寿命期间实际传播 land-value 时执行的操作完全相同处于危险之中,但 temp 而不是 land-value。这样,所有周围的补丁都会在 temp 中存储随着时间的推移从被拆除的补丁中获得的相同值 - 因此他们可以从当前的 land-value.

中减去该值

此方法的成功取决于 ask patches [set temp 0] 语句:假定 diffuse 对每个补丁进行操作,将所有 temp 设置为 0,然后执行 ask target [set temp own-residential-value]我们确保我们只重现可归因于被拆除的补丁的价值扩散模式 - 避免随着时间的推移可能发生的任何重叠,当补丁可能从其他住宅补丁收集(然后重新扩散)价值时.

(这是基于假设您在每次报价时都使用 diffuse ,正如您在对问题的评论中所说的那样。即使情况不再如此,也很容易设置 time-as-residence 根据 diffuse 自特定补丁成为住宅后发生的次数的另一种方式)

潜在问题这是你必须自己解决的问题,但考虑到还有一个可能的问题:你必须决定是否要扩散own-residential-valueland-value,这两个选项都存在一些问题。

  • 扩散 own-residential-value 对我来说似乎很直观,因为这是附加值;然而,这意味着扩散的价值将进入其他补丁的 own-residential-value(而不是进入他们的 land-value),即使它们确实没有自己的任何住宅价值,这将产生需求用于额外计算(一个可能的选择是将 own-residential-value 重命名为更合适的名称,例如 residential-value,并创建另一个 tot-value 补丁自己的变量,该变量在每个刻度更新为 set tot-value land-value + residential-value).
  • 另一方面,扩散 land-value 在编码方面会更直接(land-value 只会传播到其他补丁的 land-value),但基于什么似乎不太精确我可以理解,鉴于住宅区会传播 land-value 这通常不仅仅是它们带来的新住宅价值,而且还是之前讨论的积极反馈的结果,建立在其他住宅区的住宅价值之上。

结论

虽然我非常有信心第二种方法是可行的并且技术上很好,但我绝对更喜欢第一种方法,因为我对使用 diffuse 表示怀疑用于这个特定目标(至少基于基于我对你的意图的理解,我可能无法完全理解)- 以及在这种情况下距离函数看起来像是一种巧妙的价值扩散方法的感觉。