Netlogo:: 嗜血食人龟 & Myself/Self 混乱

Netlogo:: Bloodthirsty Cannibalistic Turtles & Myself/Self Confusion

这里是 NetLogo 的新用户和首次发帖人,手上有一些自相残杀的乌龟。

关于我的模型:

我的海龟有体型 (bsize) 和品种(雄性、雌性、幼龟)。他们以随机的方式四处走动,并在斑块上相遇。当两只海龟降落在同一块土地上时,我的小动物会互相放大,并根据较大海龟品种特有的自相残杀概率 (PrCan) 和两者之间的体型比 (bsize_ratio),大的吃小的。

我认为这无关紧要,但我使用 [=33= 创建了一个包含 3 个列表的 table (PrCanTable),其中包含两个键(体型比、品种和自相残杀概率) ] 根据我在这个堆栈溢出答案上找到的 的说明。

继续,更大的乌龟在table(PrCanTable)中查找食人概率(PrCanT),然后选择一个随机数(random-float)并将其与概率(PrCanT)进行比较.如果随机数小于或等于概率,小乌龟就死了。好伤心!

不幸的是,我的嗜血乌龟行为不端。我 运行 遇到了问题:

没有代理供MYSELF参考。 fa 25 运行 MYSELF 时出错 由过程 CANNIBALIZE 调用 由程序 GO 调用 由按钮调用 'go'

NetLogo 在我的代码中突出显示了我自己的最后一个实例,但我不知道为什么。我认为这是我对自己与自我的理解的问题。我已经尽可能多地阅读了,但老实说,我仍然感到困惑。任何人都可以看一下这段代码并告诉我吗?

to-report get-PrCan_T [ bsize_ratio_T breed_T ]
report table:get (table:get PrCanTable bsize_ratio_T) breed_T
end

to cannibalize
if ( any? turtles-here with [bsize > [bsize] of myself])
and ( random-float 1 <= get-PrCan_T ( precision( bsize / bsize of myself ) 1 ) ( [breed] of self ) )
[die]
end

是的,selfmyself 一开始会让人感到困惑,但是一旦掌握了窍门,就真的没那么难了。您需要了解的是,每段 NetLogo 代码 运行 都变成了 "context"。默认情况下,该上下文是观察者,但一些原语可以引入新的上下文。

ask 是引入新上下文的最明显方式:传递给 ask 的命令块(由 [] 分隔)将 NetLogo在乌龟的情况下。在该上下文中,self 指的是当前的海龟。

但有时您会在现有的 turtle 上下文 中引入一个新的 turtle 上下文 !在那个新上下文中,self 改变了含义:它现在指的是内部上下文中的海龟。但是,如果您仍然想从外部上下文中引用海龟怎么办?这就是 myself 的目的。

假设 cannibalize 是乌龟 运行 的过程,您在 turtles-here with [bsize > [bsize] of myself] 中使用 myself 是正确的:乌龟 运行宁with块是self(你不需要指定)和乌龟运行宁cannibalize("outer"乌龟)是myself.内部上下文由with.

引入

但是在 if 条件的第二部分(and 之后的所有内容)不再有内部上下文:您不再处于 with 块内。所以 myself 不再定义。只有self.

由于您试图将所有内容打包在相同的 if 条件下,因此您的代码也更难调试。尝试使用多个局部变量将其拆分:

to cannibalize
  let bigger-turtles-here turtles-here with [ bsize > [ bsize ] of myself ]  
  if any? bigger-turtles-here [
    let cannibal one-of bigger-turtles-here
    let ratio precision ([ bsize ] of cannibal / bsize) 1
    let p get-PrCan_T ratio breed
    if random-float 1 <= p [ die ]
  ]
end

最后一点:在你和我的版本中,执行 cannibalize 过程的乌龟 运行 是被吃掉的!这令人困惑。我要么将程序重命名为 get-cannibalized,要么将事情调换一下,使程序中的乌龟 运行 负责进食。 (命名很重要!)