子集代理集将代理列表转换为代理集
subsetting agentsets transforming a list of agents into an agentset
一个玩具示例。有两组人:A和B。只有A才能对B说"hello"。人们在世界各地行走并相遇。当人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
再次打招呼之前:
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
转换为代理集(我不知道是否有简单的方法可以做到这一点)。
有什么想法吗?
我假设您没有为 A 人或 B 人使用特定品种。
也许您可以尝试使用 breeds,例如:
breed [personA peopleA]
breed [personB peopleB]
将定义 2 个不同的代理集,然后您可以使用 <breeds>-own
语句来定义最近打招呼的人的列表。
peopleA-own [recently-greeted-people recently-greeted-people-time]
然后每次 personA 必须向某人打招呼时,您的程序可能如下所示:
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
就会被添加到不同的列表中,然后必须同时删除它们以保持一致性。
您可以阅读更多关于 breeds in the NLogo dictionary.
要将代理列表转换为代理集,请使用 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)
最后,根据您的建议,我得出了这个解决方案:
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
一个玩具示例。有两组人:A和B。只有A才能对B说"hello"。人们在世界各地行走并相遇。当人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
再次打招呼之前:
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
转换为代理集(我不知道是否有简单的方法可以做到这一点)。
有什么想法吗?
我假设您没有为 A 人或 B 人使用特定品种。
也许您可以尝试使用 breeds,例如:
breed [personA peopleA]
breed [personB peopleB]
将定义 2 个不同的代理集,然后您可以使用 <breeds>-own
语句来定义最近打招呼的人的列表。
peopleA-own [recently-greeted-people recently-greeted-people-time]
然后每次 personA 必须向某人打招呼时,您的程序可能如下所示:
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
就会被添加到不同的列表中,然后必须同时删除它们以保持一致性。
您可以阅读更多关于 breeds in the NLogo dictionary.
要将代理列表转换为代理集,请使用 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)
最后,根据您的建议,我得出了这个解决方案:
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