在Netlogo中,我有一个网格,所有的海龟都是触碰的,我想数绿海龟的数量(下面的代码是MHC=3),形成每一群绿海龟(在其他颜色中)。也许我说错了,但这似乎很难。
我尝试过green循环,设计它是从一个绿色单元开始(不连接到以前的任何绿色集群),并为它自己的变量block分配一个数字。然后每个绿色邻居in-radius 1接收相同的数字,以此类推,直到每个接触的绿色单元收到相同的数字。然后,下一个集群将收到一个新的号码,并重新开始。然而,除非这只是一个糟糕的圈套的问题,它似乎真的不起作用。下面是功能代码(它只是创建了变色海龟的网格):
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值的部分(就在勾号之前添加):
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)]]
]我认为半径可能至少是其中一个问题,我不确定它是否可以这样使用。
发布于 2021-08-24 00:17:37
更新:更简单的方法
我的初步答覆没有改变,但我认为可以采取更简单的方法:
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迭代中保留块号的情况来调整这种方法。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:
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 )。
https://stackoverflow.com/questions/68897897
复制相似问题