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
тоже.