NetLogo疏散模拟:乘客路径异常与越界问题求助
NetLogo疏散模拟问题修复
问题现象
- 乘客能移动,但无法朝向出口行进,在区域中心徘徊
- 乘客会移出房间边界
问题根源
- 移动逻辑错误:
move过程中使用move-to target-exit直接瞬移到出口,而非逐步移动,若出口不在可达区域,会直接跳出边界;同时瞬移逻辑导致乘客行为异常。 - 目标出口频繁重置:
go过程中每tick都调用choose-exit,不断切换目标出口,导致乘客无法持续朝一个方向移动。 - 无边界约束:未限制乘客只能在标记为
accessible? = true的patch上移动。
修复方案与完整代码
breed [ passengers passenger] breed [ fire-spots a-fire-spot] breed [ smoke-spots a-smoke-spot] globals [ exit1 ;; pID exit2 ;; pID exits-list ;; [ pID ... ] passenger_count ;; integer ] passengers-own [ in-seat? ;; boolean safe? ;; boolean dead? ;; boolean panic? ;; boolean current-heading ;; turtleHDG target-exit ;; pID my-exits-list ;; [ pID ... ] item? ;; boolean ] patches-own [ accessible? ;; boolean fire? ;; boolean ] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 初始化设置 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to setup __clear-all-and-reset-ticks ;;;;;; 调试信息 type "----------------------------[SETUP]\n" ;;;;;; 调试信息 initialize-globals initialize-train initialize-exits initialize-passengers ; initialize-fire reset-ticks end to initialize-globals set exit1 patch 64 -13 set exit2 patch 13 -54 set exits-list ( list exit1 exit2 ) end to initialize-train import-pcolors "C:/Users/palli/OneDrive/Desktop/Modello_base/images/ambiente.png" ask patches [ if pcolor = 86.6 [set pcolor cyan] if pcolor = 0 [set pcolor black] if pcolor = 64.3 [set pcolor green] if pcolor = 9.9 [set pcolor white] set fire? false set accessible? false ; 默认所有patch不可达 ] ask patches with [pcolor = white] [ set accessible? true ; 标记白色patch为可达区域 ] end to initialize-exits set exit1 patch 64 -13 set exit2 patch 13 -54 set exits-list (list exit1 exit2) end to initialize-passengers create-passengers passenger-count [ set shape "person business" set size 2 set color yellow set in-seat? false set safe? false set dead? false set panic? true set current-heading 0 set my-exits-list [] set target-exit nobody ; 在可达区域随机生成乘客 let target one-of patches with [accessible?] move-to target set target-exit choose-exit patch-here ; 初始化时仅分配一次目标出口 ] end to-report choose-exit [current-position] let possible-exits [] let shortest-distance 10000 let nearest-exit nobody foreach exits-list [ exitUnderTest -> let exit-distance distance exitUnderTest if exit-distance < shortest-distance [ set shortest-distance exit-distance set nearest-exit exitUnderTest set possible-exits [] ] if exit-distance = shortest-distance [ set possible-exits lput exitUnderTest possible-exits ;; 直接存储patch对象,无需转坐标 ] ] if length possible-exits = 0 [ print "未找到出口。" report nobody ] let lucky-exit one-of possible-exits set target-exit lucky-exit set my-exits-list lput lucky-exit my-exits-list report lucky-exit end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 主循环 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; to go ;;;;;; 调试信息 type "----------------------------[GO.tick]\n" ;;;;;; 调试信息 ask passengers [ if panic? and not safe? [ face target-exit ; 朝向目标出口 move ; 执行移动逻辑 ] ] tick end to move if panic? and not safe? [ ; 检查前方patch是否可达,仅在可达时移动 let next-patch patch-ahead 1 if next-patch != nobody and [accessible?] of next-patch and not [fire?] of next-patch [ fd 1 ] ; 到达出口标记为安全 if patch-here = target-exit [ set safe? true set in-seat? false ] ] end
修复说明
- 修正移动逻辑:将
move-to target-exit改为fd 1,配合face target-exit实现逐步朝出口移动;新增前方patch可达性检查,避免移出边界。 - 减少出口选择次数:仅在初始化时为乘客分配目标出口,
go过程中不再重复调用choose-exit,确保乘客持续朝一个出口移动。 - 简化
choose-exit逻辑:直接存储patch对象而非转换坐标,减少不必要的计算和错误。
内容的提问来源于stack exchange,提问作者accismns
相关产品推荐
相关产品推荐

