创建不同品种的链接NetLogo代理的社交网络

时间:2013-08-14 11:18:48

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

我正在尝试在NetLogo中组建一个“社交网络”。一群通过链接连接的不同年龄组的人。

我在如何将它组合在一起时遇到了麻烦,因为我还不完全熟悉NetLogo语法的某些部分。我在上周才开始在我的代码中使用品种,但我还没有完全解决它们。或者我让他们复杂化,我不确定。

相关代码如下,有问题的功能是“创建网络”。我需要询问每个代理(总共将有大约800个)连接到每种类型的其他代理(只要其他代理没有满了)。例如,如果乌龟属于繁殖幼崽,它将共有10个链接,其中5个连接到其他幼儿,2个连接到儿童,2个连接到成人,1个连接到45岁以上。如果第一个节点是幼儿并且它连接到成年人,我将需要减少成人节点在我到达时尝试连接的幼儿数量,如果这是有意义的话。

我无法弄清楚如何询问当前的龟是什么品种,以便我可以链接到正确的品种。如果有人能帮助我,我会非常感激。这只是代码的一小部分,但它现在让我疯狂了几天

每当我尝试某些事情时,都会导致错误,而且我完全没有想法和生活意愿。非常感谢你的时间。即使您对更好的算法有任何想法,但对代码也没有想法,也非常受欢迎

breed [toddlers toddler]
breed [children child]
breed [adults adult]
breed [over45s over45]

globals
[
  num-nodes
]

toddlers-own
[
  tod-total-connections
  tod-tods
  tod-children
  tod-adults
  tod-over45s
]

children-own
[
  child-total-connections
  child-tods
  child-children
  child-adults
  child-over45s
]

adults-own
[
  adult-total-connections
  adult-tods
  adult-children
  adult-adults
  adult-over45s
]

over45s-own
[
  over45-total-connections
  over45-tods
  over45-children
  over45-adults
  over45-over45s
]


to generate
  clear-all
  create-toddlers num-toddlers
  create-children num-children
  create-adults num-adults
  create-over45s num-over45
  create-network
  setup
  reset-ticks
end

to setup 
  ask turtles
    [reset-node]
  ask links
    [set color gray + 1.5]
  ask adults
    [set shape "circle"
      set size 4]
  ask toddlers
    [set shape "face happy"
      set size 4]
  ask over45s
    [set shape "triangle"
      set size 4]


  ;;INITIALISE BREEDS

  ;;Initialise Toddlers
  ask toddlers [set total-connections 10]
  ask toddlers [set tod-tods 5]
  ask toddlers [set tod-children 2]
  ask toddlers [set tod-adults 2]
  ask toddlers [set tod-over45s 1]

  ;;Initialise Children
  ask children [set total-connections 17]
  ask children [set child-tods 3]
  ask children [set child-children 8]
  ask children [set child-adults 5]
  ask children [set child-over45s 1]

  ;;Initialise Adults
  ask adults [set total-connections 13]
  ask adults [set adult-tods 1]
  ask adults [set adult-children 3]
  ask adults [set adult-adults 6]
  ask adults [set adult-over45s 3]

  ;;Initialise Over45s
  ask over45s [set total-connections 12]
  ask over45s [set over45-tods 1]
  ask over45s [set over45-children 1]
  ask over45s [set over45-adults 5]
  ask over45s [set over45-over45s 5]



  ;; Layout turtles:
  layout-circle (sort turtles) max-pxcor - 8
  ask turtles
  [
    facexy 0 0
    if who mod 2 = 0 [fd 4]
  ]
  display
end


;; THIS IS THE PROBLEM FUNCTION
to create-network
  let q 0
  let n 0
   while [q < count turtles]
  [
    let m 1
    while [m < count turtles]
        [
           make-link-between turtle n
                  turtle ((n + m) mod count turtles)
           set m m + 1 
;;results in a fully connected network which I don't want
         ]  
     set n n + 1
     set q q + 1
  ]

end


;; connects the two nodes
to make-link-between [node1 node2]
  ask node1 [
    create-link-with node2
      [ set color gray + 1.5]
  ]
end

我也想知道是否有可能“暂停”代理之间的链接。例如,关闭孩子之间的一些或所有链接。我知道链接有一个tie-mode属性,但我不确定这是否能够做到这一点。从我读到的内容来看,似乎更多的是将搬家代理人聚集在一起?我可以使用解开作为关闭链接但仍然存在的方式吗?

编辑:隐藏链接可能更合适。下一步是如何隐藏正确的链接

1 个答案:

答案 0 :(得分:2)

首先,让我们解决这个问题:

  

我无法弄清楚如何询问当前的龟是什么品种

海龟有a breed variable

但我认为,更多的是,你还没有接受NetLogo的做事方式。您的代码非常重要,使用while循环和索引。您应该避免使用who数字来解决海龟问题(尽管您自己的布局代码可能是一个罕见的例外)。 NetLogo完全是关于列表,代理集和(如果可能的话)功能转换。

无论如何,我认为这是解决问题的更好方法。最棘手的一点是如何计算reverse-num-connexions,但试图弄清楚它是如何工作的应该是学习如何处理列表的一个很好的练习。

另外,请注意,乌龟可能没有以所需数量的连接结束,因为它的所有目标都被最大化了。这取决于你的人口比率。

breed [ toddlers toddler ]
breed [ children child ]
breed [ adults adult ]
breed [ over45s over45 ]

to setup
  clear-all
  create-toddlers 200
  create-children 200
  create-adults 200
  create-over45s 200
  create-network
  reset-ticks
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 ]
      ]
    ]
  ]

end

reverse-num-connexions解释(编辑)

假设我们正在遍历我们的连接数列表,我们到达[toddlers adults 2]。这说明每个孩子应该与2个成年人有联系。但是,如果我们进一步查看列表,我们会发现成年人应该与不超过1名幼儿相关联:[adults toddlers 1]。这个数字(1)是我们尝试提取以存储为reverse-num-connexions

首先要做的是找到合适的子列表。这将是“源”和“目标”品种与当前品种相反的品种。表达式filter [ item 0 ? = target-breed and item 1 ? = source-breed ] connexions将返回仅包含该子列表的列表:[[adults toddlers 1]]。要提取它,我们使用first,它只提供子列表:[adults toddlers 1]。现在,我们想要该子列表的最后一项,即item 2。这将为我们提供我们追随的1