NetLogo Efficient way to create fixed number of links

萝らか妹 提交于 2019-11-28 01:28:20

Great question. This is actually quite challenging to optimize. The problematic line is:

let candidates other people with [ count my-links < friends ]

This is slow because it has every agent checking with every other agent. With 5000 agents, that's 25,000,000 checks! Unfortunately, there isn't really a good way to optimize this particular line without some fancy data structures.

Fortunately, there is a solution that generalizes really well to generating any degree distribution in the network (which it sounds like that's what you ultimately want). Unfortunately, the solution doesn't translate super well to NetLogo. Here it is though:

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

It doesn't matter if friends here is a global or a turtle variable. The amount of time this takes depends on the number of times that it needs to try making pairs, which is random. Experimenting, I found that it was usually about 3 seconds with 5000 agents, each with degree 5. This is compared to about 60 seconds on my machine with your original way of doing this (which, for what it's worth, is the way I would recommend when using fewer agents).

JenB

After debugging (see NetLogo Efficiently create network with arbitrary degree distribution), the following version is relatively efficient. It needs a global variable (called lonely below) to store the agentset of turtles that still need links. Removing individual turtles is more efficient than the nested process to create the candidate set each time.

  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 ] ]
    ]
  ]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!