NetLogo开发求助:家庭智能体选房逻辑加防占条件后报错
NetLogo模型错误修正与功能实现
需求说明
- 让家庭智能体(households)检查满足以下条件的地块(patch):①
is-home? = true;②cost ≤ 家庭的money - 将首个符合条件的地块ID赋值给家庭的
my-home变量 - 将家庭ID传入地块的
patch-owner变量 - 家庭移动到该地块
- 若未找到符合条件的地块,家庭智能体死亡,
number-displaced计数器加1
问题现状
添加and not any? households-here条件避免多家庭抢占同一地块后,点击Go按钮触发错误:MOVE-TO expected input to be an agent but got NOBODY instead.
当前代码
breed [ households household ] globals [ homes num-households number-displaced ] households-own [ my-home money owner? ] patches-own [ is-home? cost occupied? patch-owner ] to-report random-exponential-in-bounds [mid mmin mmax] let result random-exponential mid if result < mmin or result > mmax [ report random-exponential-in-bounds mid mmin mmax ] report result end to setup-households ask households [ set money round random-exponential-in-bounds 50000 0 1000000 ] end to setup-patches ask n-of 100 patches [ set is-home? one-of [ true false ] set cost 500 ];random-normal 173000 43000 ] end to setup ca set-default-shape households "person" set num-households 100 create-households num-households setup-households setup-patches reset-ticks end to choose-house ifelse any? patches with [ is-home? = true and cost <= [money] of myself and not any? households-here ] [ ask households [ move-to one-of patches with [ is-home? = true and cost <= [money] of myself and not any? households-here ] set owner? true set my-home patch-here ] set occupied? TRUE set patch-owner households-here ] [ set number-displaced number-displaced + 1 die ] end to go ask households [ choose-house ] tick end
错误原因与修正方案
核心问题
- 重复筛选导致的不一致:原代码先判断是否存在符合条件的地块,再重新筛选一次,两次筛选间隔中可能已有其他家庭抢占了地块,导致第二次筛选返回
NOBODY,触发MOVE-TO错误。 - 错误的代理调用:单个家庭执行
choose-house时,使用ask households会让所有家庭同时执行移动逻辑,加剧地块竞争且逻辑混乱。 - 变量作用域错误:
set occupied? TRUE和set patch-owner households-here让家庭智能体执行,但这些变量属于地块,会引发错误。
修正后的代码
重点修改setup和choose-house过程:
to setup ca set-default-shape households "person" set num-households 100 set number-displaced 0 ; 初始化计数器 create-households num-households setup-households setup-patches reset-ticks end to choose-house ; 先筛选并存储符合条件的地块,避免重复筛选 let available-homes patches with [ is-home? = true and cost <= [money] of myself and not any? households-here ] ifelse any? available-homes [ ; 随机选一个可用地块(若要取首个,替换为first available-homes) let target-home one-of available-homes ; 移动到目标地块 move-to target-home ; 给家庭变量赋值 set owner? true set my-home target-home ; 让目标地块更新状态和所有者 ask target-home [ set occupied? TRUE set patch-owner myself ] ] [ ; 未找到地块,计数器加1并死亡 set number-displaced number-displaced + 1 die ] end
关键优化点
- 将符合条件的地块提前存储为变量
available-homes,确保判断和使用的是同一批地块,避免竞争导致的NOBODY问题。 - 去掉不必要的
ask households,直接让当前家庭执行操作,逻辑更清晰。 - 使用
ask target-home让目标地块更新自身的occupied?和patch-owner变量,修正作用域错误。 - 在
setup中初始化number-displaced为0,避免首次计数时的未定义错误。
内容的提问来源于stack exchange,提问作者Abe
相关产品推荐
相关产品推荐

