首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算一种触碰类型的所有海龟

计算一种触碰类型的所有海龟
EN

Stack Overflow用户
提问于 2021-08-23 19:12:15
回答 1查看 191关注 0票数 0

在Netlogo中,我有一个网格,所有的海龟都是触碰的,我想数绿海龟的数量(下面的代码是MHC=3),形成每一群绿海龟(在其他颜色中)。也许我说错了,但这似乎很难。

我尝试过green循环,设计它是从一个绿色单元开始(不连接到以前的任何绿色集群),并为它自己的变量block分配一个数字。然后每个绿色邻居in-radius 1接收相同的数字,以此类推,直到每个接触的绿色单元收到相同的数字。然后,下一个集群将收到一个新的号码,并重新开始。然而,除非这只是一个糟糕的圈套的问题,它似乎真的不起作用。下面是功能代码(它只是创建了变色海龟的网格):

代码语言:javascript
复制
turtles-own[MHC block]

globals[prWound]

to set-up
  clear-all
  reset-ticks
  ask patches [sprout 1 [set color magenta]]
  ask turtles [set MHC 2]
  set prWound 0.0001
end

to rules
  ask turtles with [MHC = 0][set color red]
  ask turtles with [MHC = 1][set color green]
  ask turtles with [MHC = 2][set color magenta]
  ask turtles with [MHC = 3][set color blue]
  ask turtles with [MHC = 4][set color orange]

ask turtles [if random 100 < 1 [set MHC (random 5)] ;vary MHC betwen 0-4,
    set block 0
    if random-float 1 < prWound [ask turtles in-radius 4 [die] die] 
    if any? patches in-radius 1 with [not any? turtles-here] and random 100 < 50 [if random 100 < 2.5 
[set MHC (random 5)] hatch 1 [move-to one-of patches in-radius 1 with [not any? turtles-here]
  ]
  tick
end

to go
  rules
end

下面是我尝试添加无法工作的block值的部分(就在勾号之前添加):

代码语言:javascript
复制
  ask turtles with [MHC = 1][
    if block = 0 [set block (max([block] of turtles) + 1) ]
    while [any? [turtles with [MHC = 1 and block = 0] in-radius 1] of turtles with [block = [block] of myself]]
[if any? [turtles with [MHC = 1 and block = 0] in-radius 1] of turtles with [block = [block] of myself]
[set block ([block] of myself)]]
  ]

我认为半径可能至少是其中一个问题,我不确定它是否可以这样使用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-24 00:17:37

更新:更简单的方法

我的初步答覆没有改变,但我认为可以采取更简单的方法:

代码语言:javascript
复制
to count-blocks
  set block-now 0
  
  ask turtles [set block 0]
  
  while [any? turtles with [condition]] [
   set block-now block-now + 1
   
   ask one-of turtles with [condition] [
     join-and-search 
    ]
  ]
end


to join-and-search
  set block block-now
  
  if any? (turtles-on neighbors) with [condition] [
   ask (turtles-on neighbors) with [condition] [
      join-and-search
    ]
  ]
end


to-report condition
  ifelse (color = green and block = 0)
   [report TRUE]
   [report FALSE]
end

注意,虽然在本例中只使用过一次while,但实际上to join-and-search通过调用自己来创建一个循环,而递归调用只存在if any? (turtles on neighbor) with [condition];这使得candidate?通道(即成为候选人、招聘候选人、不再是候选人)在这里不再需要。

我认为在这种情况下应该发出警告:我不知道让过程调用自己是否是最佳实践。一方面,这听起来像是值得沮丧的事情;另一方面,在我看来,这个join-and-search不可能比任何用奇怪条件构建的其他循环更有问题。

初步答复

在试图解决这个问题时,我自己发现了一些我没有考虑到的关于in-radius的东西,当然也有部分问题。

然而,在披露这一点之前,让我说一句,我不确定这个in-radius-thing是不是你的尝试完全错了:当我发现它的时候,我已经采取了我的方法来解决这个问题。

但是,总的来说,有一点建议:尽可能保持代码的整洁和可读性(包括缩进)--发现问题所在变得容易得多。

尽管如此,我的方法的主要内容是:

  • 两个while循环:第一个循环检查整个模拟中是否有任何符合条件的海龟来启动一个新的block;第二个循环(嵌套在第一个循环中)检查是否还有海龟要分配给正在评估的当前block
  • 一个candidate? turtles-own变量,它构成第二个while循环的条件。当被分配到一个块时,每只海龟也会搜索它的邻居。如果有任何海龟应该添加到当前块,那么这些获得candidate? = TRUE和内循环再次启动。
  • 此外,我还在许多过程中使用相关名称拆分了相对较少的命令。这既提高了代码的可读性,又提高了代码的可伸缩性:当您打算扩展模型的变量、代理集、条件等时,将代码行添加到已分配的部分并检查某个特定部分是否独立工作将更加容易。
  • to-report condition和全局变量block-now的存在主要是为了提高可读性。
  • 到目前为止,这段代码在每个go上重新计数块(块可能在go的一个迭代和另一个迭代之间更改编号)。当然,可以根据您希望在go迭代中保留块号的情况来调整这种方法。
代码语言:javascript
复制
globals [
  prWound
  block-now
]

turtles-own [
 MHC
 block
 candidate?
]


to setup
  clear-all
  reset-ticks
  ask patches [sprout 1 [set color magenta]]
  ask turtles [set MHC 2]
  set prWound 0.0001
end


to go
  rules
  count-blocks
  tick
end


to rules
  ask turtles with [MHC = 0][set color red]
  ask turtles with [MHC = 1][set color green]
  ask turtles with [MHC = 2][set color magenta]
  ask turtles with [MHC = 3][set color blue]
  ask turtles with [MHC = 4][set color orange]

ask turtles [
    if random 100 < 1 [set MHC (random 5)] 
    set block 0
    if random-float 1 < prWound [ask turtles in-radius 4 [die] die]
    if any? patches in-radius 1 with [not any? turtles-here] and random 100 < 50 [
     if random 100 < 2.5 [
       set MHC random 5
      ]
      hatch 1 [move-to one-of patches in-radius 1 with [not any? turtles-here]]
    ]
  ]
end


to count-blocks
  set block-now 0
  
  ask turtles [
   set block 0
  ]
  
  while [any? turtles with [condition]] [start-count-round]
  
end


to start-count-round
  
  set block-now (block-now + 1)
  
  ask turtles [
   set candidate? FALSE
  ]
  
  ask one-of turtles with [condition] [set candidate? TRUE]
  
  while [any? turtles with [candidate?]] [
    ask turtles with [candidate?] [
     join
     search
     conclude 
    ]
  ]
end


to join
  set block block-now
end


to search
  let target (turtles-on neighbors) with [condition and not candidate?]
  ask target [set candidate? TRUE]
end


to conclude
  set candidate? FALSE
end


to-report condition
  ifelse (color = green and block = 0)
   [report TRUE]
   [report FALSE]
end

在此之前

单击以查看图像

之后

单击以查看图像

in-radius

虽然一只寻找turtles in-radius 1的海龟会发现海龟站在附近的任何一个斑块上,这似乎很直观,但事实并非如此:in-radius 实际上是一段距离的输入编号--也就是需要交叉的补丁数。

就距离而言,站立在水平或垂直相邻斑块上的海龟距离为1,而在对角线相邻斑块上站立的海龟则为1.4:

代码语言:javascript
复制
observer> clear-all
observer> ask patch 0 0 [sprout 1]
observer> ask patch 0 1 [sprout 1]
observer> ask patch 1 1 [sprout 1]
observer> ask turtle 0 [show distance turtle 1]
(turtle 0): 1
observer> ask turtle 0 [show distance turtle 2]
(turtle 0): 1.4142135623730951

这就是为什么在我用let target turtles in-radius 1 with [condition and not candidate?]取代let target (turtles-on neighbors) with [condition and not candidate?]之前,甚至我的方法都无法工作的原因。

请注意,您在共享的第一个代码块中使用了两次in-radius。在一种情况下,这只是patches in-radius 1,您可以用neighbors替换它,而在另一种情况下,则是turtles in-radius 4。在后一种情况下,您可能需要考虑距离的影响。

关于代码的最后说明

只是为了确保:您确定to rules中的事物顺序是您想要的吗?对于现在的情况,海龟会改变它们的MHC值,但只会在下一轮的go中改变颜色(但是,到那时,它们将再次改变MHC )。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68897897

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档