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

Netlogo 子集代理集将代理列表转换为代理集,netlogo,Netlogo,一个玩具的例子。有两组人:A和B。只有A可以向人们B打招呼。人们环游世界,彼此相遇。当人A遇到人B时,他们向他们打招呼。每个人都有一个向谁打招呼的记录,以及打招呼时的记号。在五次新的滴答声出现之前,他们不能向同一个人打招呼。以下步骤仅适用于人员A 每次a人a向a人B问好时,我定义: set tick-last-greeting lput ticks tick-last-greeting set previous-person-b-greeted lput selected-person-b pr

一个玩具的例子。有两组人:AB。只有A可以向人们B打招呼。人们环游世界,彼此相遇。当人A遇到人B时,他们向他们打招呼。每个人都有一个向谁打招呼的记录,以及打招呼时的记号。在五次新的滴答声出现之前,他们不能向同一个人打招呼。以下步骤仅适用于人员A

每次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来迎接,但要等到五个滴答声出现。这里是我的关键问题:如何定义一个agentset来排除列表中的代理
previous-person-b-helleed

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-helleed
转换为代理集(我不知道是否有简单的方法可以做到这一点)


有什么想法吗?

我假设您没有为A或B族使用特定的品种

也许您可以尝试使用品种,例如:

breed [personA peopleA]
breed [personB peopleB]
将定义两个不同的AgentSet,然后您可以使用
-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
请注意,对于每个迎接的
人员b
,将
who
id
添加到不同的列表中,然后必须同时删除它们以保持一致性


您可以阅读有关

的更多信息要将代理列表转换为代理集,请使用
海龟集
补丁集
链接集
。例如:

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 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

首先,如果您的代码中有一个
,那么您可能正在以一种不必要的复杂方式做一些事情。通常我会说,首先构建一个agentset,但我认为您确实需要这个列表,因为您存储了两条信息,代理和问候时间。我还没想清楚,但是我想我会做两个列表——一个是代理列表,一个是When列表——所以很容易搜索When列表,如果tick seen是很久以前的事,那么可以使用
position
从两个列表中删除信息……真正的程序员可能会做成对列表,但我对列表的处理不够好,无法描述如何过滤那些。对于代理列表,您只需使用
member?
查看代理B是否在代理A的最近问候列表中。我理解您所说的,但是,我不知道具体怎么做:我有一个代理集,还有一个我想删除的代理列表。它们有不同的长度,这就是为什么
who
似乎是最容易找到它们的方法<代码>成员?
给我一个正确或错误的答案,可能
过滤器
会很有用。代理列表的长度与这些代理的who编号列表的长度完全相同,因此使用
who
没有任何好处,只会添加代码,以便在代理与其
who
编号之间进行转换。您想要
成员?
的原因是您只关心他们是否在代理列表中-因此T/F是正确的。如果他们在名单上,那么他们就不会受到欢迎。当代理的年龄太大时,代理将从列表中删除。也就是说,您应该只跟踪在最近5个时间段内遇到的代理,您不需要保留所有遇到的代理的永久内存,只需
删除项
。非常简单:)如果有一个包含这些技巧的文档就好了!联机文档中的turtle set原语明确表示它可用于列表,请参阅