子集代理集将代理列表转换为代理集

subsetting agentsets transforming a list of agents into an agentset

一个玩具示例。有两组人:AB。只有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 个问候语,whoid 就会被添加到不同的列表中,然后必须同时删除它们以保持一致性。

您可以阅读更多关于 breeds in the NLogo dictionary.

要将代理列表转换为代理集,请使用 turtle-setpatch-setlink-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