NetLogo 创建固定数量链接的有效方法

Posted

技术标签:

【中文标题】NetLogo 创建固定数量链接的有效方法【英文标题】:NetLogo Efficient way to create fixed number of links 【发布时间】:2015-10-06 10:15:26 【问题描述】:

我的模型中有大约 5000 个代理(人)。我想给他们任意数量的朋友,并有互惠但随机的配对。因此,如果 A 人选择 B 人,那么 B 人也会选择 A 人。我的代码运行良好,但速度相当慢。我可能希望将来增加朋友的数量和人数。有更快的建议吗?

ask people
[ let new-links friends - count my-links
  if new-links > 0
  [ let candidates other people with [ count my-links < friends ]
    create-links-with n-of min (list new-links count candidates) candidates
    [ hide-link ]
  ]
]

请注意,在上面的代码中,friends 是一个全局变量,但我的最终代码可能会泛化为将 wanted-number-of-friends 作为人的属性。

EDITED 添加了if new-links &gt; 0 条件,以便在不需要找到候选人时避免嵌套ask。这提高了速度,但仍然无法真正扩展。

【问题讨论】:

【参考方案1】:

很好的问题。这实际上是相当具有挑战性的优化。有问题的行是:

let candidates other people with [ count my-links &lt; friends ]

这很慢,因为它让每个代理都与其他所有代理检查。有 5000 名代理人,那就是 25,000,000 张支票!不幸的是,如果没有一些花哨的数据结构,就没有真正优化这一行的好方法。

幸运的是,有一个解决方案可以很好地概括生成网络中的任何度数分布(听起来这就是您最终想要的)。不幸的是,该解决方案不能很好地转换为 NetLogo。不过是这样的:

  let pairs [] ;; pairs will hold a pairs of turtles to be linked
  while [ pairs = [] ] [ ;; we might mess up creating these pairs (by making self loops), so we might need to try a couple of times
    let half-pairs reduce sentence [ n-values friends [ self ] ] of turtles ;; create a big list where each turtle appears once for each friend it wants to have
    set pairs (map list half-pairs shuffle half-pairs) ;; pair off the items of half-pairs with a randomized version of half-pairs, so we end up with a list like: [[ turtle 0 turtle 5 ] [ turtle 0 turtle 376 ] ... [ turtle 1 turtle 18 ]]
    ;; make sure that no turtle is paired with itself
    if not empty? filter [ first ? = last ? ] pairs [
      set pairs []
    ]
  ]
  ;; now that we have pairs that we know work, create the links
  foreach pairs [
    ask first ? [
      create-link-with last ?
    ]
  ]

这里的friends 是全局变量还是海龟变量都没有关系。这花费的时间取决于它需要尝试配对的次数,这是随机的。进行实验时,我发现 5000 个代理通常需要 3 秒,每个代理的度数为 5。这与我的机器上的大约 60 秒相比,使用你的原始方式(就其价值而言,这是我会的方式建议使用较少的代理)。

【讨论】:

谢谢布莱恩。是的,我最终试图产生一种任意分布的方法。我知道该算法,但永远无法生成该代码(我必须在列表方面做得更好)。但是您对问题的隔离给了我另一个想法-从代理集中删除代理应该线性扩展,因此我可以尝试将候选者作为全局代理集运行并在选择它们时测试删除。如果它运作良好,将作为未来的另一个答案发布。【参考方案2】:

经过调试(见NetLogo Efficiently create network with arbitrary degree distribution),以下版本比较高效。它为仍然需要链接的海龟构造一个代理集(下面称为lonely),并在它们获得足够的链接时将其删除。删除单个海龟比每次创建候选集的嵌套过程更有效。

变量 nFriends 是一个全局变量(在原始模型中有一个滑块),它是链接的目标数量,对所有代理都相同。

  let lonely turtles with [count my-links < nFriends]
  ask turtles
  [ set lonely other lonely
    let new-links nFriends - count my-links
    if new-links > 0
    [ let chosen n-of min (list new-links count lonely) lonely
      create-links-with chosen [ hide-link ]
      ask chosen [ if count my-links = nFriends [ set lonely other lonely ] ]
    ]
  ]

【讨论】:

当我尝试这种方法时,我得到: OTHER 预期输入是一个代理集,但得到了数字 0。你有什么想法,为什么? 是的,这是一对链接问题的一部分,我们无法删除和合并,因为有答案!在执行这部分代码之前,您需要将名为孤独的代理集设置为所有海龟。我会编辑然后回答,如果它不起作用,请留下另一条评论。

以上是关于NetLogo 创建固定数量链接的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 Minted 格式化 Netlogo 代码

将物品打包到固定数量的箱子中

礼品卡

线程池

Netlogo - 从 Beta-Pert 分布中抽样

以二进制表示计数1的数量