玩具示例。有两组人: A 和 B 。只有 A 可以说"你好"对人 B 。人们走遍世界各地,相遇。当人A 遇到人B 时,他们会向他们问好。每个人 A 记录,当发生这种情况时,他们都会打招呼。他们不能向同一个人打招呼,直到五个新的蜱发生。以下程序仅适用于人A 。
每当人A 向人B 打招呼时,我定义:
set tick-last-greeting lput ticks tick-last-greeting
set previous-person-b-greeted lput selected-person-b previous-person-b-greeted
再次发出say-hello程序之前:
if (length tick-last-greeting != [] and previous-person-b-greeted != []) [
; wait 5 ticks
set temp (map [ticks - ? > 5] tick-last-greeting)
; filter the list, I don't know if there is a better way to do this
set previous-person-b-greeted (map last filter [first ? = false] (map list temp previous-person-b-greeted))
set tick-last-greeting (map last filter [first ? = false] (map list temp tick-last-greeting))
]
所以,我得到一个人B 的列表,不应该被人A 打招呼,但直到五个滴答声发生。这是我的关键问题:如何定义排除列表previous-person-b-greeted
的代理的代理集。
set potential-persons-b targets-on (patch-set neighbors patch-here)
if (previous-person-b-greeted > 0) [
; Here, I get an error as expected
let who-previous-person-b [who] of previous-person-b-greeted
set potential-persons potential-persons with [who != who-previous-person-b]
]
一种可能的解决方案:将列表previous-person-b-greeted
转换为代理集(我不知道是否有简单的方法可以执行此操作)。
有什么想法吗?
答案 0 :(得分:2)
要将代理列表转换为代理集,请使用turtle-set
或patch-set
或link-set
。例如:
observer> create-turtles 5
observer> let mylist (list turtle 0 turtle 2 turtle 4) print turtle-set mylist
(agentset, 3 turtles)
答案 1 :(得分:1)
我会假设您没有为A人或B人使用特定品种。
也许您可以尝试使用品种,例如:
breed [personA peopleA]
breed [personB peopleB]
将定义2个不同的代理集,然后您可以使用<breeds>-own
语句来定义最近受欢迎的人员列表。
peopleA-own [recently-greeted-people recently-greeted-people-time]
然后每当一个人必须问候某人时,你的程序可能如下:
to greet [personB-who]
if (not (and (member? personB-who recently-greeted-people)
(procedure-that-checks-ticks-less-than-5))
...ADD HERE OTHER LOGICAL CHECKS DEPENDING ON YOUR PROBLEM
)
[
fput personB-who recently-greeted-people
fput current-tick recently-greeted-people-time
]
end
请注意,对于每个personB
,who
和id
会被添加到不同的列表中,然后必须同时将其删除以保持一致。
答案 2 :(得分:0)
最后,根据您的建议,我最终得到了这个解决方案:
set potential-persons-b sort (targets-on (patch-set neighbors patch-here))
if (previous-person-b-greeted != [])
[
foreach previous-victimized-target
[ set potential-persons-b remove ? potential-persons-b]
set potential-persons-b turtle-set potential-persons-b
]
这是使用to-report
的更通用的解决方案:
to-report subsetting-agents [agent-set1 agent-set2]
set agent-set1 sort agent-set1
set agent-set2 sort agent-set2
foreach agent-set2
[ set agent-set1 remove ? agent-set1]
set agent-set1 turtle-set agent-set1
report agent-set1
end