Переместить агентов в узел на основе условия в Netlogo - PullRequest
0 голосов
/ 31 октября 2019

Я хотел бы создать сеть в Netlogo, разместить 3 агентов на первом узле сети и заставить их переместиться на подключенный узел.

В частности, я бы хотел, чтобы агенты выбирали узел для перемещенияна основе вероятности. Если на подключенном узле нет агента, выберите его с помощью p = 0,5 , если есть , то агент на узле выберите его с помощью p = 0,7 . Так что, если - например - у начального узла есть два соседних узла, и на одном из них есть другой агент, его следует выбирать с большей вероятностью.

Мне удалось создать сеть и переместитьагенты случайным образом, но я не могу понять, как заставить агента «знать», если на узле есть другой агент, и установить вероятности на основе этого условия.

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 и не знаю всех возможностей и ограничений, поэтому возможно, что я смотрю на эту проблему совершенно неправильно. Буду признателен за вашу помощь.

1 Ответ

0 голосов
/ 02 ноября 2019

Сиелу, пара моментов.

Во-первых, создание ссылки молча завершится неудачей, если между этими двумя узлами уже есть связь. В результате у некоторых из ваших узлов будет только один сосед. Если это не так, вам нужно поработать над логикой создания ссылок.

Во-вторых, это может быть неочевидно, но некоторые узлы будут иметь более двух ссылок, поэтому у проходящего может быть много разных путей кВыбери из.

В-третьих, узел может иметь более одного пассажира. Например, все остальные ходоки могут быть на нем.

Учитывая все это, я собираюсь предположить, что вы запрашиваете, чтобы каждый ходок начал смотреть на свои связанные узлы, установил некоторую вероятность, основываясь на занятости целевого узла, выберитеслучайное число, и если оно ниже этой вероятности, переместитесь в этот узел и перестаньте смотреть на другие возможные ходы. Если же случайное число выше этой вероятности, тогда бродягу следует забыть об этой ссылке и перейти к рассмотрению следующей. Если все ссылки не проходят свои отдельные тесты, обходчик не двигается.

Код ниже реализует это. Это было довольно долго и грязно. Вот ключевые особенности.

  • Я добавил многословно? переключатель, который включает или выключает распечатку деталей для отладки, и спрашивает пользователя, быть ли многословным или нет в каждой настройке. Если вы нажмете кнопку go один раз (не навсегда), вы сможете увидеть, что установлено, и если это то, что вы хотели.

  • Я добавил число проходов к каждому узлу по сравнению с истинным /ложное размещение? switch

  • Я добавил порядковый номер (например, «кто») для каждого наблюдателя, чтобы сделать вывод более понятным

  • , шаг GO делаетСПИСОК узлов, которые являются соседями по ссылке к узлу, на котором стоит наблюдатель. Затем он сортирует список в том порядке, в котором вы хотите их изучить. (Я использовал список, потому что вас может волновать, в каком порядке они просматриваются, а наборы агентов упорядочены случайным образом.) Я отсортировал их по возрастанию в порядке возрастания по количеству занятых, поэтому сначала он будет смотреть на незанятые узлы, затем на занятые. , до самых занятых.

  • Затем он проходит через этот список, решая, двигаться ли к этому узлу или нет. Как только он решает переехать, он перестает смотреть на список, поэтому некоторые узлы даже не будут рассматриваться как ход.

  • Вы можете увидеть раздел, в котором вероятности установлены в зависимостина счетчик занятости узла. Я использовал ваши вероятности 0,5 и 0,7 и добавил вероятность 0,9, если на целевом узле присутствуют 2 или более наблюдателей.

  • В коде много комментариев, и если вы установите подробный текст? истинно, вы можете проверить, как каждый наблюдатель рассматривает (или не учитывает) каждую ссылку и принимает решение о ее перемещении или нет.

Код работает и выглядит нормально, насколько ямогу сказать, чего ты хочешь. Задайте мне вопросы, если неясно, что я сделал.

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