Создание социальной сети связанных агентов NetLogo разных пород
Я пытаюсь собрать что-то вроде "социальной сети" в NetLogo. Группа людей разных возрастных групп, которые связаны ссылками.
У меня возникли проблемы с тем, как его собрать, потому что я до сих пор не полностью знаком с некоторыми частями синтаксиса NetLogo. Я только начал использовать породы в своем коде на прошлой неделе, и я еще не полностью разработал их. Или я слишком усложняю их, я не уверен.
Ниже приведен соответствующий код с рассматриваемой функцией "create-network". Мне нужно попросить каждого агента (всего их будет около 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, но я не уверен, что это может сделать это. Из того, что я прочитал, похоже, больше связано с объединением движущихся агентов? Могу ли я использовать untie как способ отключения ссылки, но чтобы она все еще присутствовала?
Изменить: Скрыть ссылку может быть более подходящим. Как скрыть правильные ссылки это следующая вещь
1 ответ
Во-первых, давайте уберем это с пути:
Я не могу понять, как спросить нынешнюю черепаху, что это за порода
Черепахи имеют переменную породу.
Но я думаю, что в целом вы еще не смирились с 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
что мы были после.