使用嵌套询问访问 netlogo 中的自有特征

Accessing owned traits in netlogo with nested ask

这就是我想要做的:

patches-own[
trait1
trait2
trait3
]

let similarityCounter 0

ask one-of patches[

    ask one-of neighbors[

        **for-each trait[

            if neighborTrait = patchTrait**[

                set similarityCounter (similarityCounter + 1)

            ]
        ]
    ]
]

** 之间的部分是我不确定的部分。如何迭代补丁自己的参数并比较补丁和邻居?

如何为特征值的每个补丁创建一个列表并计算两个列表中的匹配项?它看起来像这样。

to testme
  let similarityCounter 0
  ask one-of patches
  [ let mytraits (list trait1 trait2 trait3)
    let theirtraits [(list trait1 trait2 trait3)] of one-of neighbors
    set similarityCounter length filter [ xx -> xx ] (map = mytraits theirtraits)
  ]
end

最后一行有点密集。它所做的是使用 map 函数和 = 运算符比较两个特征列表,这将 return truefalse 值的列表表明该特定特征是否匹配。 filter 然后创建一个仅包含 true 值的列表,length 计算这些 true 值的数量。

不幸的是,NetLogo 不会像您在某些语言中看到的那样将 true 视为 1 并将 false 视为 0,因此您不能简单地 sum比赛结果列表。

我真的很喜欢 Jen 的回答,但为了好玩,我想提供一种替代方法来解决使用 Jen 将 true 视为 1 和 [=16 的想法的问题=] 作为 0.

但首先,我认为,根据模型的其余部分,将特征直接存储在列表中而不是单独的变量中可能是个好主意。在编程中,变量名带有数字后缀,如 trait1trait2 等,通常暗示应改用列表。

尽管如此,我们暂时不考虑您的总体设计,只提供一个小功能,可以轻松地将您的特征打包到列表中:

to-report traits ; patch reporter
  report (list trait1 trait2 trait3)
end

一旦你有了它,你可以写类似 [ traits ] of one-of patches 的东西来获得补丁的特征列表。

现在让我们以类似的方式解决将 truefalse 变成 1 和 0 的问题。诚然,NetLogo 不会自动提供该对话(我认为这是一件好事),但为此编写我们自己的函数很容易:

to-report bool-to-int [ yes? ]
  report ifelse-value yes? [ 1 ] [ 0 ]
end

我们现在准备编写我们的主要功能。我们将使用 Jen 映射 = 运算符的方法将我们的特征列表转换为布尔值列表(即 true/false)值,然后我们将使用 map 再次将该列表转换为 10 的列表。一旦我们有了它,剩下的就是 sum 它了!我们开始吧:

to-report similarity-with [ other-patch ] ; patch reporter  
  report sum map bool-to-int (map = traits [ traits ] of other-patch)
end

有了那个记者,就可以很容易地获得两个补丁之间的相似性。你现在可以这样说:

print [ similarity-with one-of neighbors ] of one-of patches

请注意我是如何通过构建组合在一起的小块来解决问题的。我真的很喜欢这种处理方式:它让我一次可以专注于问题的一部分,但它也更容易测试并生成我认为非常易读的代码。 NetLogo 的 to-report 程序是实现这种模块化的好工具。