Netlogo, присваивая переменную соседям

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

Патчи собственные = готовность к использованию и привлекательность землепользования

Что я хочу: участки, которые готовы изменить, должны изменить свое землепользование на землепользование соседа с самой высокой привлекательностью (чем ближе к 0, тем привлекательнее)

Я попытался сделать это с помощью следующего утверждения:

to askforchange
  ask patches [
    if Willingstochange = true  [change]   ;; this ask the patches that are willing to change (have a surpuls) to go and change
  ]
end


to change
  ask neighbors with [Willingstochange = false ]  [         ;; this asks if the patch had neigbors with a shortage
  set Atractiveneighbor min-one-of patches [atractiveness]  ;; this asks to give the neigbor with the lowest patchcount/senario ratio
  ]


  ask patches with [Willingstochange = true]  [
    set Land-use ([Land-use] of Atractiveneighbor)   ;; this asks the patches to change their land-use to the land-use of neigbor with the lowest patchcount/senario ratio
  ]     

end

Однако при запуске Netlogo сообщает: "OF ожидал, что входными данными будет набор агентов черепахи или набор исправлений агента, или черепаха, или заплатка, но вместо этого он получил число 0".

Кто-нибудь предлагает, как кодировать это так, как это работает?

Весь мой код:

extensions [gis]
globals
[
  land-use-map
   Senario1N               ;; the count of patches senario 1 describes
   Senario1L
   Senario1A
   Senario1B
   Senario1I
   Senario1R
   Senario1W
  %landusetypeN           ;; the amount patches
  %landusetypeL
  %landusetypeA
  %landusetypeB
  %landusetypeI
  Atractiveneighbor

]

patches-own
  [   Land-use                ;; Wat kind og landusetype a patch has
      Willingstochange        ;; If true a patch would like to change (if true the count of patches has a surplus comparing to the sneario, if false they have a shortage)
      atractiveness           ;; if a patch type is attractive to change in <1 = yess
    ]



to setup
  clear-all
  load-gis                       ;;load the maps
  setup-constants
  update-global-variables
  update-display
  reset-ticks
end



to load-gis  ;;load the maps
  set land-use-map gis:load-dataset "a_LANDUSE_cellsize5.asc"     ;;loads the land use map
  gis:set-world-envelope-ds gis:envelope-of land-use-map          ;;sets the envelope of the world to match that of the GIS dataset
  gis:apply-raster land-use-map Land-use                          ;;patches in the land-use-map have a specific land-use now

  ask patches [
    if Land-use = 1 [ set pcolor Green ] ; Green = Nature         ;; patches have a certain color now
    if Land-use = 2 [ set pcolor red ] ; Dark red = Leisure
    if Land-use = 3 [ set pcolor Yellow ] ; Yellow = Agriculture
    if Land-use = 4 [ set pcolor brown ] ; brouwn = Buildup
    if Land-use = 5 [ set pcolor grey ] ; grey = roads
    if Land-use = 6 [ set pcolor pink ] ; pink = industry
    if Land-use = 7 [ set pcolor blue ] ; Blue = water
  ]
    resize-world 0 1633 0 780
    set-patch-size 1
end

to setup-constants
  set Senario1N 49174        ;; the count of patches senario 1 describes
  set Senario1L 17871
  set Senario1A 569970
  set Senario1B 34202
  set Senario1I 5540
  set Senario1R 34968
  set Senario1W 65594

end


to go ;; this asks the model to caculate certain variables defined below
  askforchange
  caculateWILLingtochange
  caculateAtrac
  tick
end


to update-display
  ask patches
  [ if Land-use = 1 [ set pcolor Green ]   ;; Green = Nature           
    if Land-use = 2 [ set pcolor red ]     ;; Dark red = Leisure
    if Land-use = 3 [ set pcolor yellow ]  ;; Yellow = Agriculture
    if Land-use = 4 [ set pcolor brown ]   ;; brouwn = Buildup
    if Land-use = 5 [ set pcolor grey ]    ;; grey = roads
    if Land-use = 6 [ set pcolor pink ]    ;; pink = industry
    if Land-use = 7 [ set pcolor blue ]    ;; Blue = water
    ] ;; patches have a certain color now
end

to update-global-variables
  if count patches > 0
    [ set %landusetypeN (count patches with [ Land-use = 1 ] / count patches) * 100
      set %landusetypeL (count patches with [ Land-use = 2 ] / count patches) * 100
      set %landusetypeA (count patches with [ Land-use = 3 ] / count patches) * 100
      set %landusetypeB (count patches with [ Land-use = 4 ] / count patches) * 100
      set %landusetypeI (count patches with [ Land-use = 6 ] / count patches) * 100
    ]
end



to caculateWILLingtochange
  Ask  patches [
    if count patches with [Land-use = 1] > Senario1N [ ask patches with [ Land-use = 1 ][
           set  Willingstochange True
         ] ]

    if count patches with [Land-use = 2] > Senario1L [ ask patches with [ Land-use = 2 ][
           set  Willingstochange True
         ] ]
    if count patches with [Land-use = 3] > Senario1A [ ask patches with [ Land-use = 3 ][
           set  Willingstochange True
         ] ]
    if count patches with [Land-use = 4] > Senario1B [ ask patches with [ Land-use = 4 ][
           set  Willingstochange True
         ] ]
    if count patches with [Land-use = 5] > Senario1R [ ask patches with [ Land-use = 5 ][
           set  Willingstochange True
         ]]
    if count patches with [Land-use = 6] > Senario1I [ ask patches with [ Land-use = 6 ][
           set  Willingstochange True
         ]]
    if count patches with [Land-use = 7] > Senario1W [ ask patches with [ Land-use = 7 ][
           set  Willingstochange True
         ] ]  ]
end

to caculateAtrac
  Ask  patches [
    if count patches with [Land-use = 1] > Senario1N [ ask patches with [ Land-use = 1 ][
           set  atractiveness (count patches with [Land-use = 1]/ Senario1N )
         ] ]

    if count patches with [Land-use = 2] > Senario1L [ ask patches with [ Land-use = 2 ][
           set  atractiveness (count patches with [Land-use = 2]/ Senario1L )
         ] ]
    if count patches with [Land-use = 3] > Senario1A [ ask patches with [ Land-use = 3 ][
           set  atractiveness (count patches with [Land-use = 3]/ Senario1A )
         ] ]
    if count patches with [Land-use = 4] > Senario1B [ ask patches with [ Land-use = 4 ][
            set  atractiveness (count patches with [Land-use = 4]/ Senario1B )
         ] ]
    if count patches with [Land-use = 5] > Senario1R [ ask patches with [ Land-use = 5 ][
            set  atractiveness (count patches with [Land-use = 5]/ Senario1R )
         ]]
    if count patches with [Land-use = 6] > Senario1I [ ask patches with [ Land-use = 6 ][
             set  atractiveness (count patches with [Land-use = 6]/ Senario1I )
         ]]
    if count patches with [Land-use = 7] > Senario1W [ ask patches with [ Land-use = 7 ][
             set  atractiveness (count patches with [Land-use = 7]/ Senario1W )
         ] ]  ]
end


to askforchange
  ask patches [
    if Willingstochange = true  [change]   ;; this ask the patches that are willing to change (have a surpuls) to go and change
  ]
end


to change
  ask neighbors with [Willingstochange = false ]  [         ;; this asks if the patch had neigbors with a shortage
  set Atractiveneighbor min-one-of patches [atractiveness]  ;; this asks to give the neigbor with the lowest patchcount/senario ratio
  ]

  ask patches with [Willingstochange = true]  [
    set Land-use ([Land-use] of Atractiveneighbor)   ;; this asks the patches to change their land-use to the land-use of neigbor with the lowest patchcount/senario ratio
  ]     

end

1 ответ

Ваша проблема в том, что вы спрашиваете neighbors with [Willingstochange = false ] в set глобальная переменная Привлекательный сосед. Таким образом, если нет соседей, не желающих меняться, то эта переменная имеет значение по умолчанию (равное 0), потому что никто не устанавливает его. Кроме того, вы на самом деле хотите минимум соседей, но спрашиваете все патчи.

Это исправит вашу непосредственную проблему (не проверено). Обратите внимание, что процедура запускается только для patches with [Willingstochange = true] так что вам не нужно проверять это в рамках процедуры.

to change
  set Atractiveneighbor min-one-of neighbors [atractiveness]
  set Land-use ([Land-use] of Atractiveneighbor)
end

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

to change
  let Atractiveneighbor min-one-of neighbors [atractiveness]
  set Land-use ([Land-use] of Atractiveneighbor) 
end

Даже чище (хотя, возможно, труднее читать для нового кодера NetLogo), вы можете сделать это:

to change
  set Land-use [Land-use] of min-one-of neighbors [atractiveness]
end

Еще лучше, зачем проводить проверку в отдельной процедуре? Вы можете полностью удалить процедуру изменения и сделать:

to askforchange
  ask patches with [Willingstochange]
  [ set Land-use [Land-use] of min-one-of neighbors [atractiveness]
  ]
end

Помимо объединения двух процедур, это заменяет ask patches [ if Willingstochange = true] [] с ask patches with [ Willingstochange = true] [] (с помощью with), а также использует преимущества более простого true а также false кодирование где true предполагается (вы можете использовать not Willingstochange вместо Willingstochange = false тоже.

Другие вопросы по тегам