根据 Netlogo 中的条件将代理移动到节点

Move agents to a node based on a condition in Netlogo

我想在 Netlogo 中创建一个网络,将 3 个代理放在网络的第一个节点上,并使它们移动到连接的节点。

具体来说,我希望代理根据概率选择要移动到的节点。如果连接的节点上没有代理,则选择p = 0.5,如果节点上有代理,则选择p = 0.7。因此,如果 - 例如 - 起始节点有两个相邻节点,其中一个节点上有另一个代理,则应该以更高的概率选择它。

我已经设法创建了网络并随机移动了代理,但我不知道如何创建一个代理 "know" 如果节点上有其他代理并设置概率在这种情况下。

breed [nodes node]
breed [walkers walker]

walkers-own [location ]

to setup
  clear-all
  set-default-shape nodes "circle"
  create-nodes 18 [set color white]
  ask nodes [ create-link-with one-of other nodes ]
  layout-circle nodes 10
  create-walkers 3 [
    set location node 1
    move-to location
  ]
  reset-ticks
end

to go
  ask walkers [
    let new-location one-of [link-neighbors] of location ;; choose a new location randomly
    move-to new-location
    set location new-location
  ]
  tick
end

我想制作一个 occupied? 变量并根据代理的位置更新它,但它会是一个 nodes-own 变量,我无法连接到代理(walkers).

我是 Netlogo 的新手,不了解所有的可能性和限制,所以我可能完全错误地看待这个问题。非常感谢您的帮助。

Sielu,两点。

首先,如果这两个节点之间已经存在 link,则创建 link 将无提示地失败。结果是您的某些节点最终将只有一个邻居。如果不行,您需要处理 link 创建逻辑。

其次,可能不明显,但有些节点最终会超过两个link, 所以步行者可能有许多不同的路径可供选择。

第三,一个节点可能有多个占用者。例如,所有其他助行器可能都在上面。

考虑到所有这些,我将假设您要求的是让每个步行者开始查看其 linked 节点,根据目标的占用率设置一些概率节点,select 一个随机数,如果它低于该概率,则移动到该节点并停止查看其他可能的移动。但是,如果随机数高于该概率,那么步行者应该忘记 link 并继续考虑下一个。如果所有 link 都未通过各自的测试,则助行器不会移动。

下面的代码实现了这一点。它有点长而且凌乱。这是主要功能。

  • 我加了啰嗦?打开或关闭打印细节以进行调试的开关 并且它会询问用户是否在每个设置上都冗长。如果你打 去一次(不是永远)你可以看到设置了什么,如果它是你想要的。

  • 我为每个节点添加了步行者计数,而不是 true/false 占用率?开关

  • 我为每个观察者添加了一个序列号(如 "who" )以进行输出 多读书

  • GO 步骤生成一个节点列表,这些节点是观察者节点的 link 邻居 站在。然后它将列表排序为您要检查的顺序 他们。 (我使用了一个列表,因为你可能关心它们的查看顺序,并且 代理集是随机排序的。 )我将它们按升序排列 占用率很重要,所以它会首先查看未占用的节点,然后是 占用的,最多占用最多的。

  • 然后遍历该列表,决定是否移动到该节点。 一旦决定移动,它就会停止查看列表,因此一些节点 甚至不会考虑搬家。

  • 您可以看到根据入住率设置概率的部分 节点的计数。我使用了你的 0.5 和 0.7 概率并添加了 0.9 目标节点上有 2 个或更多观察者的概率。

  • 代码注释较多,是否设置verbose?为真,你可以 检查每个观察者如何考虑(或不考虑)每个 link 并使其成为 决定搬还是不搬。

代码运行起来看起来不错,据我所知你想要什么。问我 如果不清楚我做了什么,请提问。

breed [nodes node]
breed [walkers walker]

walkers-own [location seqnum ]  ;; seqqnum is like who but for the walkers

nodes-own[ count-of-walkers ]    ;; ADDED

globals [verbose?]

to setup
  clear-all
  set verbose? false                     ;; if true, prints a lot for debugging purposes
  if user-yes-or-no? "Print debugging info on each step?" [set verbose? true]

  set-default-shape nodes "circle"
  create-nodes 18 [set color white]
  ask nodes [ create-link-with one-of other nodes ]
  layout-circle nodes 10
  let seq 1               ;; start of sequence numbers for walkers
  create-walkers 3 [
    set size 3
    set color red
    set location node 1
    set seqnum seq set seq seq + 1  ;; assign the sequence number
    move-to location
    ask location [ set count-of-walkers count-of-walkers + 1 ]
  ]
  reset-ticks
end

to go
  if verbose? [print "    ================================== starting the go loop"]
  ask walkers [

    let candidate-set []  ;; this will be an agent set of neighboring linked nodes

    ask location [set candidate-set link-neighbors ]  ;; ask my node to find its neighbors

    ;; sort the neighbors into some order and make a list of them
    ;; the next line sorts them into ascending order by occupancy ( lowest first )
    ;; we will consider a move to each one in that order

    let candidate-list sort-on [count-of-walkers] candidate-set  

    if verbose? [
     type "walker " type seqnum
     type " is checking out these neighbors: " print candidate-list
    ]

    ;;     Examine each neighbor and decide whether to move there based on probabilities
    ;;     if we find a place to move we like  terminate processing the list
    ;;     otherwise, remove that candidate neighbor from the list
    ;;     and keep doing that until the list is empty
    ;;  

    while [length candidate-list > 0 ]  [        ;; while we haven't decided to move yet


        ;; pop the first item off the list  
        let candidate first candidate-list            ;; pull the first item
        set candidate-list but-first candidate-list   ;; and remove it from the list

      ;; decide what probability to use for considering THIS move
       let prob-of-move 0  ;; a default value
       let occupant-count [ count-of-walkers ] of candidate ;; count walkers on that node

       if occupant-count = 0 [ set prob-of-move 0.5 ]
       if occupant-count = 1 [ set prob-of-move 0.7 ]
       if occupant-count > 1 [ set prob-of-move 0.9 ]

      if verbose? [
       type " ... candidate " type candidate
       type " has this many walkers " type [count-of-walkers] of candidate
       type " so set probability of move to " print prob-of-move
      ]

      ;; make a decision to move or not based on that probability
        if-else random-float 1 < prob-of-move [
        if verbose? [type  " ......moving to " print candidate]
        ;;let new-location candidate
        set candidate-list []  ;; make the list empty so this WHILE loop will exit
        move-to candidate      ;; move the walker on the display

        ;; update the counts of walkers on each affected node
        ask candidate [ set count-of-walkers count-of-walkers + 1 ]
        ask location  [ set count-of-walkers count-of-walkers - 1 ]

        ;; finally, tell the walker where it is now
        set location candidate

      ]
      [if verbose? [ print " ..... was not selected for a move to this node"]]

    ]

    if verbose? [ print " ..............done with processing walkers for this tick"]

    ]
  tick
end