是否有可能要求代理离开代理集而不依赖于NetLogo中的变量?



尽管NetLogo有一组很好的原语,可以方便地创建代理集,但有时我们可能想让代理"手动"将自己添加到代理集,作为它们正在运行的过程的一部分——例如,通过使用turtle-set

的例子:

globals [
good-folks
bad-folks 
]
to setup
clear-all

set good-folks (turtle-set)
set bad-folks (turtle-set)

create-turtles 50 [
ifelse (random 2 < 1)
[set good-folks (turtle-set good-folks self)]
[set bad-folks (turtle-set bad-folks self)] 
]
end
to go
ask good-folks [
do-good-things 
]

ask bad-folks [
do-bad-things 
]
end
to do-good-things end
to do-bad-things end

上面这种方法的优点是可读性更好,可以避免创建海龟自己的变量,避免使用withif语句——如下所示:

turtles-own [
group 
]
to setup
clear-all

create-turtles 50 [
ifelse (random 2 < 1)
[set group "good folks"]
[set group "bad folks"]
]
end
to go1
ask turtles with [group = "good folks"] [
do-good-things 
]

ask turtles with [group = "bad folks"] [
do-bad-things 
]
end
; OR
to go2
ask turtles [
ifelse (group = "good folks")
[do-good-things]
[do-bad-things]
]
end
to do-good-things end
to do-bad-things end

特别是,在我看来,后一种方法不像前者那样顺利地扩展,即更多的组将需要更多的withs或ifs,而不仅仅是能够整齐地引用所需的组。

然而,我不知道有一种方法可以做到与set good-folks (turtle-set good-folks self)完全相反,即要求海龟"手动"从代理集中删除自己。

; In this case, bad-folks try to recruit some good folks
to do-bad-things
if (random 3 < 2) [
ask one-of good-folks [
set good-folks (turtle-set good-folks - self) ; Leave the good folks <- **How to do this?**
set bad-folks (turtle-set bad-folks self) ; Join the bad folks
] 
]
end

我知道这可以通过使用海龟自己的变量,然后更新agentsets作为set <good/bad>-folks turtles with [...]来实现,但这正是我在这个问题中试图避免的整个事情:可读性较差,更多变量,更多命令等。而且,也许同样重要的是,它看起来与turtle-set结合使用self来增长代理集的方法不一致。如果存在一种从代理集中减去self的方法,它看起来会更容易和更一致——它存在吗?

更新Jasper的解决方案(即使用品种而不是agentsets)只要我想要跟踪的组是相互排斥的就可以工作:代理从一个单一品种切换到另一个单一品种只需要set breed ...,这将使代理加入新品种离开原来的品种。但是,如果我想跟踪具有重叠的多个组,这将不起作用:除了good-folksbad-folks,我可能有tall-folksshort-folks。agent必须同时属于多个组——这是agentset可以处理而breed不能处理的。

也许我错过了你的要求,但难道品种不会让你很容易做到这一点吗?你可以使用set breed BREED-NAME来改变它,它会自动从它现有的品种中移除乌龟。如果这是你的目标,你甚至可以多删减一些代码,我认为它看起来更清晰了。

breed [ good-folks goodie ]
breed [ bad-folks  baddie ]
to setup
clear-all

create-turtles 50 [
ifelse (random 2 < 1) [
set breed good-folks
] [
set breed bad-folks
]
]
end
to go
ask good-folks [
do-good-things 
]

ask bad-folks [
do-bad-things 
]
end
to do-good-things end

to do-bad-things
if (random 3 < 2 and any? good-folks) [
ask one-of good-folks [
set breed bad-folks  
] 
]
end

答案,这是我意识到以下一些思路后贾斯珀的答复,实际上很简单,它只需要other:

to do-bad-things
if (random 3 < 2) [
ask one-of good-folks [
set good-folks (turtle-set other good-folks) ; Leave the good folks
set bad-folks (turtle-set bad-folks self) ; Join the bad folks
] 
]
end

额外的廉价思想

这也让我觉得如果NetLogo有两个叫做joinleave的原语就很方便了,它们的工作方式是:

to join [agentset]
(ifelse
is-turtle? self [
set agentset (turtle-set agentset self)
]
is-patch? self [
set agentset (patch-set agentset self)
]
; else command:
[set agentset (link-set agentset self)])
end
to leave [agentset]
(ifelse
is-turtle? self [
set agentset (turtle-set other agentset)
]
is-patch? self [
set agentset (patch-set other agentset)
]
; else command:
[set agentset (link-set other agentset)])
end

所以我们可以这样做:

to do-bad-things
if (random 3 < 2) [
ask one-of good-folks [
leave good-folks
join bad-folks
] 
]
end

感觉就像在看书而不是在看代码;虽然我认识到它的必要性最终是微乎其微的。

最新更新