有效地停用社交网络中特定代理和品种之间的特定链接

时间:2013-08-21 16:10:30

标签: social-networking netlogo agent-based-modeling

NetLogo中设置了不同年龄段的代理社交网络,类似于以下内容,这导致一系列通过链接连接的代理。这些链接的总体目的是表示这些链接之间的联系。该模型模拟了通过网络传播的传播。代理人开始易受影响,如果他们与传染性的链接邻居接触,则有可能被感染。我想模拟一个受感染个体的隔离或隔离。即,他们与其他人的链接将被完全停用,或者至少他们的大多数链接将被停用。理想情况下,我会按下观察者界面上的按钮来停用受感染代理的链接。我还希望能够模拟学校的关闭,例如大多数幼儿和儿童以及他们之间的联系将被停用,从而阻止儿童之间的感染能力。他们与成年人的联系可能应该保持开放,如果他们更少,但是现在只关注一个品种之间的联系可能更好。

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的帮助

编辑:添加了链接自己的布尔值来关闭?

尝试更改计算打开链接上受感染邻居数量的部分,但是我收到错误 this code can't be run by a link error while link 14 15 running SET called by procedure SPREAD called by Button '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变量,据我所知,但是当我把一只手表放在一只乌龟上并运行模拟时,一只乌龟被感染的邻居似乎一直超过乌龟所拥有的链接邻居的实际数量。这也是错的。我不明白为什么......

编辑:

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是该列表的长度

1 个答案:

答案 0 :(得分:2)

首先提出一些一般建议:最好给出一个最小工作示例(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,然后测试它们的颜色。然后,对于通过测试的每个链接,我要求它为other-end,即通过my-links找到链接的乌龟不是乌龟。然后将病毒传播到该乌龟 - 但前提是该链接尚未被禁用。 (我认为这段代码工作正常 - 似乎。但如果你这样做,你应该彻底测试它。)使用my-links计算禁用或未禁用的链接应该更容易。对于isolate-infected,您可以执行ask turtles with [infected?] [ask my-links [set颜色/停用/等操作。 ]]。没有测试过。

对于编辑版本中的新错误以回应我的回答,我认为问题可能是这段代码:

ask my-links with [closed? = false][
  set num-infected-neighbors count (link-neighbors with [infected? = true])
]

这要求一些链接运行过程link-neighbors,但该过程仅设计为由海龟运行。 (在NetLogo中,某些过程只能被设计为由“代理”运行,例如在ask ...之后的大括号内。但是,其中一些过程仅在海龟代理中起作用,而其他过程仅在链接代理中起作用。 )您可能应该使用other-end,这是一个旨在由链接运行的过程。 (但这是一个有趣的过程,因为它只是设计为在请求链接运行ask的{​​{1}}命令时由链接运行,是由other-end调用的所以ask只有在你有other-end之类的东西时才有效。)

(可以在第一个代理ask turtle 1 [ask mylinks [ ... other-end ...]]编辑的另一个代理中引用代理。对于其中一个级别,您可以使用ask。对于myself s的其他级别,你可以在外层定义变量,然后在内层引用它们。)