Сиелу, пара моментов.
Во-первых, создание ссылки молча завершится неудачей, если между этими двумя узлами уже есть связь. В результате у некоторых из ваших узлов будет только один сосед. Если это не так, вам нужно поработать над логикой создания ссылок.
Во-вторых, это может быть неочевидно, но некоторые узлы будут иметь более двух ссылок, поэтому у проходящего может быть много разных путей кВыбери из.
В-третьих, узел может иметь более одного пассажира. Например, все остальные ходоки могут быть на нем.
Учитывая все это, я собираюсь предположить, что вы запрашиваете, чтобы каждый ходок начал смотреть на свои связанные узлы, установил некоторую вероятность, основываясь на занятости целевого узла, выберитеслучайное число, и если оно ниже этой вероятности, переместитесь в этот узел и перестаньте смотреть на другие возможные ходы. Если же случайное число выше этой вероятности, тогда бродягу следует забыть об этой ссылке и перейти к рассмотрению следующей. Если все ссылки не проходят свои отдельные тесты, обходчик не двигается.
Код ниже реализует это. Это было довольно долго и грязно. Вот ключевые особенности.
Я добавил многословно? переключатель, который включает или выключает распечатку деталей для отладки, и спрашивает пользователя, быть ли многословным или нет в каждой настройке. Если вы нажмете кнопку 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