在 NetLogo 中建立了一个由不同年龄的代理组成的社交网络,类似于以下内容,从而形成一个通过链接连接的代理圈。这些链接的总体目的是表示这些链接之间的联系。该模型模拟感染通过网络的传播。特工一开始很容易受到感染,如果他们接触到具有传染性的邻居,就有可能被感染。例如,我想对受感染者的隔离或检疫进行建模。即他们与其他人的链接将被完全停用,或者至少其大部分链接将被停用。理想情况下,我会按观察者界面上的按钮来停用受感染代理的链接。我还希望能够模拟学校关闭,例如,大多数幼儿和 child 以及他们之间的联系将被停用,从而阻止 child 之间感染的能力。如果它们的数量较少,它们与成年人的联系可能应该保持开放,尽管现在最好一次只关注一个品种之间的联系。
breed [ toddlers toddler ]
breed [ children child ]
breed [ adults adult ]
breed [ over45s over45 ]
globals
[
num-nodes
num-infected
num-susceptible
prob-infection-toddler
prob-infection-child
prob-infection-adult
prob-infection-over45
force-of-infection
]
turtles-own
[
temp-infected? ;; temporary infected state
infected? ;; true if agent has been infected
susceptible?
num-infected-neighbors
]
links-own
[
closed?
]
to setup
clear-all
create-toddlers 20
create-children 20
create-adults 20
create-over45s 20
create-network
reset-ticks
layout-circle (sort turtles) max-pxcor - 8
ask turtles
[
facexy 0 0
if who mod 2 = 0 [fd 4]
]
ask turtles
[set susceptible? true]
ask one-of turtles
[
set infected? true
set susceptible? false
set color red
]
display
end
to create-network
let connexions (list
(list toddlers toddlers 5)
(list toddlers children 2)
(list toddlers adults 2)
(list toddlers over45s 1)
(list children toddlers 3)
(list children children 8)
(list children adults 5)
(list children over45s 1)
(list adults toddlers 1)
(list adults children 3)
(list adults adults 6)
(list adults over45s 3)
(list over45s toddlers 1)
(list over45s children 1)
(list over45s adults 5)
(list over45s over45s 5)
)
foreach connexions [
let source-breed item 0 ?
let target-breed item 1 ?
let num-connexions item 2 ?
let reverse-num-connexions item 2 first filter [
item 0 ? = target-breed and item 1 ? = source-breed
] connexions
ask source-breed [
repeat num-connexions [
let possible-targets other target-breed with [
(not member? myself link-neighbors) and
(count link-neighbors with [ breed = source-breed ] < reverse-num-connexions)
]
let target one-of possible-targets
if target != nobody [ create-link-with target ]
]
]
]
ask links [set closed? false]
end
to spread
;;; there is one of these for each age group as they have different probabilities for infection
ask toddlers with [ susceptible? = true ]
[
;;tried changing to something like this but this is the line that throws up an error
ask my-links with [closed? = false][
set num-infected-neighbors count (link-neighbors with [infected? = true])
]
;;should only include active links
set force-of-infection (prob-infection-toddler) ^ num-infected-neighbors ;;paraphrased equation but num-infected-neigbours is important
if ( random-float 1 <= force-of-infection) ;; infect with probability p
[
set temp-infected? true
set susceptible? false
]
]
ask turtles with [temp-infected? = true]
[
set infected? true
set temp-infected? false
]
end
to isolate-infected
;;for all infected individuals deactivate their links
end
to close-schools
ask toddlers
[
ask my-links [set closed? true]
]
end
to close-offices
;; e.g cut the number of links between adults and so on
end
正如您所看到的,这里有两个问题,一个是根据终端节点所处的状态来停用链接(理想情况下,一旦学校关闭结束或受感染的个人康复后,它们可以再次打开)或它们的品种。
第二个问题是计算受感染链接邻居的数量,而不包括已停用的链接。隐藏链接并不会阻止其存在,它只是变得不可见,因此不会阻止联系。我还考虑过简单地将停用链接的颜色更改为黑色。有没有一种方法可以重写受感染邻居的计数,以仅计算非黑色或隐藏的链接,例如 set num-infected-neighbors count (link-neighbors with [infected? = true]
...并且链接隐藏? = false.... 或链接颜色“!= 黑色? )
我觉得第二个问题可能是这两个问题中更容易的一个,但我可能错了。在这个阶段我碰过太多的砖墙,我对这件事很头疼。任何帮助将不胜感激。感谢您花时间阅读本文,我意识到这有点咆哮:) 再次感谢 Nicolas Payette 之前的帮助
编辑:添加了链接自己的 bool 值以关闭?
尝试更改计算打开链接上受感染邻居数量的部分,但出现错误
此代码无法通过链接运行
链接 14 15 运行 SET 时出错
由过程 SPREAD 调用
由按钮“Spread”调用
还在“关闭学校”中添加了一个功能,通过设置关闭来基本关闭所有幼儿链接?为真
编辑:这是否是一个可能的解决方案
set num-infected-neighbors 0
ask my-links with [closed? = false][
ask other-end [if (infected?) [set num-infected-neighbors num-infected-neighbors + 1 ]]
]
set force-of-infection 1 - (1 - prob-infection-adult) ^ num-infected-neighbors
编辑:据我所知,num-infected-neighbors 应该是一个turtles-own
变量,但是当我给乌龟戴上 watch 并运行模拟时,num-infected-海龟拥有的邻居数量似乎始终超过海龟拥有的链接邻居的实际数量。这也是错误的。但我不明白为什么......
编辑:
let infectnum 0
set num-infected-neighbors 0
ask my-links with [closed? = false][
ask other-end [if (infected?) [set infectnum infectnum + 1 ]]
;;set num-infected-neighbors count (link-neighbors with [infected? = true])
]
set num-infected-neighbors infectnum
似乎也无法正常工作...
编辑:供将来引用问题已解决 -
set num-infected-neighbors length filter [[infected?] of ?]
[other-end] of my-links with [not closed?]
首先,由未关闭链接上的链接邻居组成一个列表,然后对其进行过滤,仅给出受感染的链接。 num-infected-neighbors 是该列表的长度
最佳答案
首先一些一般性建议:最好给出一个最小工作示例(MWE),即被精简到最低限度以显示问题的示例。这段代码细节太多,所以人们不太可能回答。而且,有时一旦你把它拆开,你就会找到答案。此代码也不起作用:缺少全局变量的定义。
您可能想看看 NetLogo 附带的模型库中的“网络上的病毒”。它做类似的事情,但使用更“NetLogoey”的编码风格。
您可以测试链接的颜色。即,您可以使用链接是“停用”颜色的事实来测试是否应该计算或跟踪它。更好的想法是使用 links-own
为链接提供一个变量,并对其进行测试。但这里有一些示例代码(根据“网络病毒”中的过程修改)使用颜色来实现此目的:
to spread-virus
ask turtles with [infected?]
[ ask my-links with [color != red]
[ask other-end
[ if (not resistant?) and (random-float 100 < virus-spread-chance)
[ become-infected ] ] ] ]
end
诀窍在于,我不是直接查看link-neighbors
,而是向每只乌龟询问其my-links
,然后测试它们的颜色。然后,对于通过测试的每个链接,我会询问其另一端
,即不是通过my-links
找到链接的乌龟。然后病毒就会传播给那只乌龟——但前提是链接没有被禁用。 (我认为这段代码工作正常——似乎是这样。但是如果你这样做,你应该彻底测试它。)使用my-links
计算禁用或非禁用链接> 应该更容易。对于isolate-infected
,您可以使用询问海龟[infected?] [ask my-links [set
color/deactivated/etc]。 ]]
。还没有测试过。
对于编辑版本中响应我的回答的新错误,我认为问题可能是这段代码:
ask my-links with [closed? = false][
set num-infected-neighbors count (link-neighbors with [infected? = true])
]
这要求一些链接运行link-neighbors
过程,但该过程仅设计用于由海龟运行。 (在 NetLogo 中,某些程序只能设计为“由代理”运行,例如在 ask ...
之后的大括号内。但是,其中一些程序仅在海龟代理中工作,而其他程序则仅适用于链接代理。)您可能应该使用 other-end
,这是一个设计为由链接运行的过程。 (不过,这是一个有趣的过程,因为它仅设计为当要求链接运行other-end
的ask
命令是一个ask
由海龟调用。因此 other-end
仅在您有类似 askturtle 1 [ask mylinks [ ... other-end ] 的情况下才有效。 ..]]
.)
(可以引用第一个代理询问
的另一个代理内的代理。对于其中一个级别,您可以使用myself
。对于其他级别的代理问
,您可以在外部级别定义变量,然后在内部级别引用它们。)
关于social-networking - 有效地停用社交网络中特定代理和品种之间的特定链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18362549/