这就是我想要做的事情:
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)
]
]
]
]
**之间的部分是我不确定的。如何迭代补丁自己的参数并在补丁和邻居之间进行比较?
答案 0 :(得分:3)
如何为每个特征值补丁创建一个列表并计算两个列表中的匹配?它看起来像这样。
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
函数和=
运算符比较两个特征列表,它将返回true
和false
值的列表,指示该特定特征是否火柴。然后,filter
会创建仅包含true
值的列表,length
会计算这些true
值的数量。
不幸的是,NetLogo没有把你在某些语言中看到的true
视为1和false
视为0的技巧,所以你不能简单地{{1匹配结果列表。
答案 1 :(得分:2)
我非常喜欢Jen的回答,但为了好玩,我想提供一种替代方法来解决使用Jen将true
视为1
和false
的想法的问题为0
。
但首先,我认为,根据模型的其余部分,将特征直接存储在列表而不是单独的变量中可能是个好主意。在编程中,使用带有trait1
,trait2
等数字后缀的变量名称通常暗示应该使用列表。
尽管如此,我们暂时保留您的一般设计,只提供一个小功能,可以轻松将您的特征打包到列表中:
to-report traits ; patch reporter
report (list trait1 trait2 trait3)
end
一旦你有了这个,你可以写一些像[ traits ] of one-of patches
这样的东西来获得一个patche的特征列表。
现在让我们以类似的方式解决将true
和false
变为1和0的问题。 NetLogo确实没有自动提供该对话(我认为这是一件好事)但是为此编写我们自己的函数很容易:
to-report bool-to-int [ yes? ]
report ifelse-value yes? [ 1 ] [ 0 ]
end
我们现在准备编写我们的主要功能。我们将使用Jen的=
运算符映射方法将我们的特征列表转换为布尔值(即true
/ false
)值列表,然后我们将使用{{ 1}}再次将该列表转换为map
和1
的列表。一旦我们拥有了,剩下的就是0
它!我们走了:
sum
有了那个记者,很容易得到两个补丁之间的相似性。你现在可以这样说:
to-report similarity-with [ other-patch ] ; patch reporter
report sum map bool-to-int (map = traits [ traits ] of other-patch)
end
请注意我是如何通过构建组合在一起的小块来解决问题的。我真的很喜欢这种方式:它允许我一次专注于问题的一部分,但它也更容易测试并产生我觉得非常易读的代码。 NetLogo的print [ similarity-with one-of neighbors ] of one-of patches
程序是实现这种模块化的一个很好的工具。