2015-10-06 102 views
2

我的模型中有大約5000個代理(人員)。我想給他們任意數量的朋友,並有相互配對但隨機的配對。所以如果人A選擇人B,那麼人B也選擇人A.我的代碼工作正常,但相當緩慢。我可能會想增加朋友的數量和未來的人數。有什麼更快的建議?NetLogo創建固定數量鏈接的高效方式

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

注意,朋友是在上面的代碼中的全局變量,但我最終的代碼可能會推廣到具有wanted-number-of-friends作爲人的屬性。

EDITED新增if new-links > 0條件,使在沒有候選人需要找到嵌套ask是可以避免的。這提高了速度,但仍不能真正縮放。

回答

2

偉大的問題。這實際上是相當具有挑戰性的優化。該問題的行是:

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

這是緩慢的,因爲它的每劑與其他所有檢查功能。有5000名代理商,這是2500萬支票!不幸的是,沒有一些奇特的數據結構,沒有一種好的方法來優化這個特定的產品線。

幸運的是,有一種解決方案可以很好地推廣到在網絡中生成任何程度的分佈(這聽起來就是你最終想要的)。不幸的是,該解決方案不能很好地轉換成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秒鐘進行比較,使用您的原始方式執行此操作(對於它的價值,這是我的方式建議何時使用較少的代理)。

+1

謝謝布萊恩。是的,我試圖最終產生一種任意分配方法。我意識到這種算法,但永遠無法生成該代碼(我必須使用列表更好)。但是,對問題的分離給了我另一個想法 - 從代理集中移除代理應該線性擴展,以便我可以嘗試運行候選作爲全局代理集並在選擇時測試刪除。如果運作良好,將作爲未來的另一個答案發布。 – JenB

0

調試結束後(參見NetLogo Efficiently create network with arbitrary degree distribution),以下版本相對有效。它需要一個全局變量(下面稱爲lonely)來存儲仍需要鏈接的海龜代理集。去除單獨的龜比嵌套過程更有效,每次創建候選集。

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