我有两个品种,买家和供应商,买家正在建立供应商列表(sup_list),这些供应商的列表'att'中存储的属性大于列表'b'中存储的标准列表。以下行为第一个标准执行此操作 - 是否有一种简单的方法可以添加所有其他标准?
ask buyers [set sup_list suppliers with [item 0 att > [item 0 b] of myself]]
所以在英语中,标准是:第0项>项目0和项目1>项目1和项目2>第3项等。
谢谢。
答案 0 :(得分:10)
你想要的表达是:
suppliers with [ reduce and (map > att [ b ] of myself) ]
这是一个棘手的功能编程。让我们看看它是如何运作的。
我们的第一个目标是获取两个数字列表并将其转换为一个布尔值列表,如果项目位于买方列表中的相同位置,则每个项目将为true
大于供应商列表中同一位置的项目。例如,如果我们有:
[1 1 1 1]
[2 1 1 1]
...只有供应商列表中的第一项符合我们的标准,因此我们希望得到的结果列表为:
[true false false false]
每当我们想要将一个或多个事物列表转换为单个事物列表时,要使用的NetLogo原语是map
。 map
原语需要记者和一个或多个列表。它将报告者应用于从列表中获取的项目,并从中构建新的列表。这正是我们所需要的。在NetLogo命令中心中尝试:
observer> show (map > [2 1 1 1] [1 1 1 1])
observer: [true false false false]
有几点需要注意:
map
,我们需要将整个表达式放在括号内。>
作为记者传递。这也可以写成[ [a b] -> a > b ]
。现在我们有了布尔值列表,我们想检查所有这些值是否为true
,即所有供应商项目是否符合买方的标准。 NetLogo有一个all?
原语,可以为代理集做类似的事情,但我们不能在这里使用它,因为我们正在处理一个列表。我们将不得不使用reduce
。
reduce
原语是我们想要将列表转换为单个值时使用的原语。在这里,我们希望将布尔列表转换为单个布尔值,如果列表中的所有值都是true
,则为true
,否则为false
。
正如NetLogo文档所说,"很难形成对reduce
做什么"的直觉。 (我强烈建议您阅读文档并尝试使用原语。)简而言之,它遍历一个列表并将记者应用于每个项目和一个"累加器" value,将该操作的结果存储在累加器中。列表的第一项用于初始化累加器。
在我们的案例中,与reduce
一起使用的记者将是and
,因为我们要检查第一项是true
,和第二项是true
,和,第三项是true
等。
让我们尝试减少之前获得的布尔值列表:
observer> show reduce and [true false false false]
observer: false
(并非我们再次使用简洁的语法将and
作为记者传递。这可以写成[ [p q] -> p and q ]
。)
最终结果为false
,因为并非所有值都为真。让我们一步一步看看它是如何工作的:
true
。and
报告者。累加器为true
,但第二项为false
。 true and false
的结果为false
,因此会将false
存储在累加器中。and
报告者。累加器现在为false
,第二项也为false
。 false and false
的结果是false
,因此它再次将false
存储在累加器中。false
,第四项也是false
。 false and false
的结果是false
,因此它再次将false
存储在累加器中。一旦我们用完了列表项,reduce
就会报告累加器的值,在本例中为false
。它报告true
的唯一情况是,如果列表中的所有值都是true
,则会导致true and true
比较序列,这些比较都会导致true
存储在累加器中。这正是我们想要的:
observer> show reduce and [true true true true]
observer: true
如果你将所有这些放在一起,你应该能够看到:
suppliers with [ reduce and (map > att [ b ] of myself) ]
...为您提供符合买方所有标准的供应商代理商!
(请注意,with
会返回代理集,而不是列表,因此您可能应该重命名sup_list
变量...)