#netlogo #agent-based-modeling
#netlogo #моделирование на основе агентов
Вопрос:
Я пишу модель рынка жилья NetLogo и его политические последствия. В модели есть две породы: домохозяйства и дома. Ранний шаг в моей разработке, с которым я сталкиваюсь с трудностями, — это сопоставление домохозяйств с домами с помощью одного из двух типов ссылок, собственных или арендуемых, определяемых вложенными условными операторами. Это привело к двум трудностям, которые я пока не смог преодолеть.
- В рамках команды
setup-market
command я пытаюсь определить набор возможных домов для покупки для каждого домохозяйства, которые, если они соответствуют набору условий, домохозяйство затем покупает (и создаетlink
). Если он не может позволить себе купить, он попытается арендовать. Если он не может позволить себе арендовать домашнее хозяйствоdie
.
Мой код постоянно приводит к следующей ошибке:
IFELSE expected input to be a TRUE/FALSE but got the turtle (house XXX) instead.
- Существует еще одна проблема, с которой я сталкиваюсь позже в коде (в двух строках, закомментированных с помощью «;»), где я пытаюсь установить переменные
owner-occupied
иrenter
на1
основе наличия соответствующей ссылки (они должны оставаться равными 0, и домохозяйство должно умереть, если оно останется несвязанным).
Полный код приведен ниже. Строка с «;; Это строка, вызывающая у меня проблемы», обозначает, где, по-видимому, возникает ошибка.
ОБНОВЛЕНИЕ: Код был обновлен с помощью решения JenB. Результирующая ошибка now: CREATE-LINK-WITH expected input to be a turtle but got NOBODY instead.
которая возникает в строке: create-link-with one-of potentialHomes [ set color red
undirected-link-breed [own-links own-link]
undirected-link-breed [rent-links rent-link]
breed [city-centers city-center]
breed [households household]
households-own
[
age
money
income
monthly-income
consumption
monthly-consumption
hh-size race
preference
net-income
net-monthly-income
myHouse
]
breed [houses house]
houses-own
[
cost
down-payment
mortgage-payment
rent
rent-premium
rooms
onMarket
owner-occupied
rental
onMarket?
]
patches-own [
seed? ;;district seed
district ;;district number
full? ;;is the district at capacity?
quadrant
]
to setup
clear-all
reset-ticks
setup-patches
set-default-shape households "person"
create-households num-households [ setxy random-xcor random-ycor ]
set-default-shape houses "house"
create-houses num-houses [ setxy random-xcor random-ycor ]
setup-households
setup-houses
setup-market
generate-cities
end
to generate-cities
let center-x random-xcor / 1.5 ;;keep cities away from edges
let center-y random-ycor / 1.5
end
to setup-patches
ask patches with [pxcor > 0 and pycor > 0] [set quadrant 1 set pcolor 19 ]
ask patches with [pxcor > 0 and pycor < 0] [set quadrant 2 set pcolor 49 ]
ask patches with [pxcor < 0 and pycor < 0] [set quadrant 3 set pcolor 139 ]
ask patches with [pxcor < 0 and pycor > 0] [set quadrant 4 set pcolor 89 ]
end
to setup-households
ask households
[ set age random-poisson 38
set money random-exponential 30600
set income random-exponential 64324
set monthly-income income / 12
set consumption .5 * income
set monthly-consumption consumption / 12
set hh-size random 6 1
set net-income income - consumption
set net-monthly-income monthly-income - monthly-consumption
]
end
to setup-houses
ask houses
[ set cost random-normal 300000 50000
set down-payment cost * down-payment-rate
set mortgage-payment (cost - down-payment) / 360
set rooms random-exponential 3
set onMarket 1
set rent mortgage-payment mortgage-payment * .25
set owner-occupied 0
set rental 0
]
end
to setup-market
ask houses
[ set onMarket? TRUE ]
ask households
[ ifelse any? houses with [ [money] of myself > down-payment and [net-monthly-income] of myself > mortgage-payment ]
[ let potentialHomes houses with [[money] of myself > cost and onMarket? ]
create-link-with one-of potentialHomes [
set color red
]
]
[
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [ [net-monthly-income] of myself > rent and onMarket? ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
]
]
ask houses
[ if any? link-neighbors [set onMarket FALSE ]
;if any? link-neighbors and color red [ set owner-occupied 1 ]
;if any? link-neighbors and color blue [ set rental 1 ]
]
end
to go
move-households
tick
end
to move-households
ask households [
move-to myHouse
]
end
Ответ №1:
Вам не нужно «подозревать», в чем проблема, NetLogo указывает на проблемную строку. Запуск вашего кода, проблема на самом деле ifelse one-of houses with [ [net-monthly-income] of myself > rent]
. Глядя на эту строку, вы вытаскиваете случайно выбранный дом из пула с арендной платой меньше, чем доход. Но у вас нет условия для ifelse
тестирования.
В предыдущих конструкциях у вас было != nobody
в конце, но вы забыли, что в этой строке. Это исправит ошибку, но ваш код был бы гораздо менее подвержен ошибкам, если бы вы использовали any?
вместо этого. Вы, кажется, используете one-of .... != nobody
для проверки, есть ли какие-либо черепахи, которые удовлетворяют условию. Вот any?
для чего.
Поэтому вместо:
ifelse one-of houses with [ [net-monthly-income] of myself > rent] != nobody
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
вы можете иметь:
ifelse any? houses with [ [net-monthly-income] of myself > rent]
[ let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
create-link-with one-of potentialRentals [ set color blue ]
]
[ die ]
Я должен добавить, что здесь есть потенциальная логическая проблема. Скажем, есть дома с арендной платой ниже, чем доход, код переходит к первым (истинным) действиям. Но нет никакой гарантии, что есть какие-либо дома, которые удовлетворяют новым условиям, которые отличаются.
Кроме того, в NetLogo есть концепция true
и false
, поэтому вам не нужно использовать 1 и 0. По соглашению (но не обязательно) имена логических переменных заканчиваются вопросительным знаком. Таким образом, вы могли бы иметь set onMarket? true
вместо set onMarket 1
. Зачем вам это делать? Это делает логические операторы более чистыми и удобными для чтения (что уменьшает количество ошибок). Ваша строка:
let potentialRentals houses with [[money] of myself > rent and onMarket = 1 ]
будет выглядеть так:
let potentialRentals houses with [[money] of myself > rent and onMarket? ]
И вы можете делать такие вещи, как if not onMarket?
вместо if onMarket? = false
или if onMarket = 0
Комментарии:
1. Спасибо за ответ. Я не был хорошо знаком с
any?
командой, поэтому ваши отзывы невероятно полезны. Я также привыкаю к синтаксису NetLogo (обычно я кодирую на R), поэтому?
полезно иметь в виду использование в качестве логического оператора.2. Я не совсем уверен в логической проблеме, которую вы определили, и надеюсь, что вы сможете немного прояснить. Чего я пытаюсь достичь, так это логики: (1) домашнее хозяйство ищет дом, для которого оно может позволить себе первоначальный взнос из сбережений (
money>down-payment
) иnet-monthly-income>mortgage-payment
; если ни один дом не удовлетворяет (1), то (2) домашнее хозяйство ищет аренду, где оно может позволить себе ежемесячную арендную плату; если ни один дом не удовлетворяет (2), затем (3) домашнее хозяйство умирает. Я понял, что неправильноnet-monthly-income
определил переменную по крайней мере в одном месте в OP; Я опубликую исправление. Еще раз спасибо за руководство.3. Еще один комментарий: скорректированный код теперь выдает ошибку:
CREATE-LINK-WITH expected input to be a turtle but got NOBODY instead.
Это происходит в строке:create-link-with one-of potentialHomes [ set color red
. Возможно, это связано с вашей выявленной логической проблемой? (Хотя я все еще не совсем уверен в проблеме.)4. @Abe пожалуйста, не обновляйте свой пост последующими вопросами после предоставления ответа — это не так, как работает SO; если ответ разрешил первоначально сообщенную проблему, пожалуйста, примите его и откройте новый вопрос с новой проблемой (ссылка здесь, если необходимо).