Netlogo, как удалить связь между черепахами на основе их стоимости - PullRequest
0 голосов
/ 10 июня 2018

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

ПробовалЧтобы решить проблему с помощью следующего блока кода, который, кажется, не работает должным образом, часто получают сообщение об ошибке

"OF expected input to be a turtle agentset or turtle but got NOBODY instead."

, относящееся к значению friend_dif

   ask turtles with [(connections > 0) and (color = blue)][
      let friends_inverse ( 1 / connections )  
      if friends_inverse > random-float 1[
       let friend_dif abs([world_view] of self - [world_view] of one-of other link-neighbors)
       ask max-one-of links [friend_dif][
         die
       ]
   ]
set connections count link-neighbors
]

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

turtles-own [connections world_view]

to setup
 ca
 crt potential_recruits [setxy random-xcor random-ycor set color blue]

  ask turtles with [color = blue][
   let przypisania random max_start_recruits_connections
   ;; 0-0.4 non interested, 0.4-0.7 moderate, 0.7-0.9 symphatizing, >0.9      radical -  can be recrouted
    set world_view random-float 1

    if count my-links < 10 [
      repeat przypisania [
        create-link-with one-of other turtles with [(count link-neighbors < 10) and (color = blue)]
      ]
    ]
    show link-neighbors 
    set connections count link-neighbors
  ]

  crt recruiters [setxy random-xcor random-ycor set color orange]

    ask turtles with [color = orange][
    set world_view 1
    if strategy = "world view"[
      recruit_view
    ]
    if strategy = "most central"[
      recruit_central
    ]
  ]

  ;;show count links
  reset-ticks
  setup-plots
  update-plots

end

to go

  ;;creating new links with turtles they meet and movement which is random
    ask turtles [
    rt random-float 360
    fd 1
    if any? other turtles-here[
    let world_view1 [world_view] of one-of turtles-here
    let world_view2 [world_view] of one-of other turtles-here
    let connection_chance abs(world_view1 - world_view2)
      if connection_chance <= 0.2 [
        ;;show connection_chance
        create-links-with other turtles-here
      ]
    ]

    ;;show link-neighbors
    set connections count link-neighbors
  ]

    ;;how recruiting works in this model
    ask turtles with [world_view > 0.9][
      if count in-link-neighbors with [color = orange] > 0[
        set color orange
        set world_view 1
      ]
    ]

  ;; friend's influence on turtles
  ask turtles with [(count link-neighbors > 0) and (color = blue)][
    let friends_view (sum [world_view] of link-neighbors / count link-neighbors)
    let view_dev (friends_view - world_view)
    ;;show world_view show view_dev
    set world_view world_view + (view_dev / 2)
  ]

  ;; removing turtles from with most different opinion from our colleagues
  ask turtles with [(connections > 0) and (color = blue)][
    let friends_inverse ( 1 / connections )  
    if friends_inverse > random-float 1[
        let friend_dif abs([world_view] of self - [world_view] of one-of other link-neighbors)
        ask max-one-of links [friend_dif][
          die
        ]
    ]
    set connections count link-neighbors
  ]
  ;show count links
  tick
  update-plots

end

to recruit_view
    ask max-n-of start_recruiters_connections turtles with [ color = blue][world_view][
      repeat start_recruiters_connections[
        create-link-with one-of other turtles with [ color = orange]
      ]
   ]
    ask turtles with [color = orange][
      set connections count link-neighbors
    ]
end

to recruit_central
   ask max-n-of start_recruiters_connections turtles with [ color = blue][count my-links][
    repeat start_recruiters_connections[
      create-link-with one-of other turtles with [ color = orange]
    ]
   ]
    ask turtles with [color = orange][
      set connections count link-neighbors
    ]
end

to batch
  repeat 50 [
  go
  ]

end

1 Ответ

0 голосов
/ 10 июня 2018

Ваша проблема в том, что вы не переключаете контексты (то есть, является ли код «текущим» в перспективе черепахи или ссылки).

Вы начинаете с ask turtles - притворяйтесьтеперь вы первая черепаха, о которой вас спрашивают.Сначала вычисляется значение, а затем сравнивается со случайным числом - предположим, что if выполнено.Код все еще находится в контексте черепахи, поэтому код внутри [] применяется к этой первой черепахе.

Код создает переменную friend_dif и присваивает ее значение как разницу в мировоззрениях между собой и однимслучайно выбранные сетевые соседи.В вашем коде у вас есть max-one-of links [friend_dif].Тем не менее, это только выбирает link с максимальным значением friend_dif, если (1) friend_dif является атрибутом links-own и (2) значение friend_dif было set для всех ссылок.Ни то, ни другое не правда.Кроме того, запрашивая max-one-of links [friend_dif], вы запрашиваете link с самым высоким значением из всех links в модели, а не только с turtle, представляющими интерес на одном конце.

Таким образом, вам нужно получить turtle, чтобы вычислить разницу для всех его link-neighbors, а затем переключить контексты на link, который соединяет двух черепах, перед тем, как запросить link к die.

Это не проверено.Предполагается, что он должен определить соседа сети, который возвращает наибольшую разницу в значениях мировоззрения, а затем использовать имя link (которое задается двумя концами), чтобы задать его die.

ask turtles with [ count my-links > 0 and color = blue]
[ if random-float 1 < 1 / count my-links
  [ let bigdif max-one-of link-neighbours [abs ([worldview] - [worldview] of myself)
    ask link self bigdif [die]
  ]
]

В качестве альтернативы (и удобнее для чтения) вы можете создать атрибут link, в котором будет храниться значение различий в мировоззрениях (называемое diff ниже), а затем сделать что-то вроде:

ask links [ set dif abs ([worldview] of end1 - [worldview] of end2) ]
ask turtles with [ count my-links > 0 and color = blue]
[ if random-float 1 < 1 / count my-links
  [  ask max-one-of my-links [dif] [die]
  ]
]
...