NetLogo网络模拟:导入含时间戳的Agent移动数据方法咨询
需求说明
我在基于智能体的模型(ABM)中构建了一个传感器网络,佩戴信标的动物(对应现有代码中的walkers种群)作为移动智能体,可在相互连通的传感器节点间移动。目前代码仅支持随机移动到相邻节点,我需要导入包含唯一智能体ID、所在节点ID、时间戳的真实移动数据,来模拟动物的实际移动路径。
现有NetLogo代码
breed [nodes node] breed [walkers walker] breed [wildlifes wildlife] undirected-link-breed [paths path] undirected-link-breed [wlpaths wlpath] walkers-own [ location list-locations carrier? nb-carrier ] ;; holds a node nodes-own [ infected? nb-infected-node ] wildlifes-own [ infectious? ] turtles-own [node-id] paths-own [strength] globals [ paths-list ] to import-network clear-all set-default-shape nodes "circle" import-attributes layout-circle (sort nodes) (max-pxcor - 1) import-paths reset-ticks end ;; 读取节点属性文件,包含唯一节点ID to import-attributes file-open "attributes.txt" while [not file-at-end?] [ let items read-from-string (word "[" file-read-line "]") create-nodes 1 [ set node-id item 0 items set size item 1 items set color blue ] ] file-close end ;; 读取节点连接文件,包含起点、终点、连接强度 to import-paths file-open "links.txt" while [not file-at-end?] [ let items read-from-string (word "[" file-read-line "]") ask get-node (item 0 items) [ create-path-with get-node (item 1 items) [ set label item 2 items ] ] ] file-close end ;; 根据节点ID查找对应节点的工具过程 to-report get-node [id] report one-of nodes with [node-id = id] end to setup clear-all import-network wildlife-nodes ask nodes [ set infected? false ] create-walkers 5 [ set shape "arrow" set color yellow set carrier? false set nb-carrier 0 set location one-of nodes with [ node-id = 1 ] set list-locations (list location) move-to location ] reset-ticks end to go if all? nodes [ infected? ] [ stop ] ask paths [ set thickness 0 ] ask nodes [ infect-walker ] ask walkers [ transmit-disease let new-location one-of [ path-neighbors ] of location ask [path-with new-location] of location [ set thickness 0.5 ] face new-location move-to new-location set location new-location set list-locations fput location list-locations ] ask wildlifes [ infect-node ] tick end to infect-walker let walker-on-node one-of walkers-here if infected? and walker-on-node != nobody and transmission-rate < random 100 [ ask one-of walkers-here [ set carrier? true set color violet set nb-carrier nb-carrier + 1 ] ] end to transmit-disease ifelse carrier? and biosec-compliance-rate < random 100 [ ask nodes-here [ set infected? true set color red set nb-infected-node nb-infected-node + 1 ] ] [ set carrier? false ] end to wildlife-nodes create-wildlifes 1 [ setxy min-pxcor max-pycor set color green set shape "tree" set size 2 set infectious? false create-wlpaths-with n-of 2 nodes ] end to infect-node if trans-rate-from-wildlife > random 100 [ ask one-of wlpath-neighbors [ set infected? true ] ] end
实现步骤
1. 准备移动数据文件
创建CSV格式的移动数据文件(命名为walker-movements.csv),每行包含三列,用逗号分隔:
agent-id:智能体的唯一标识(整数)node-id:该时间点智能体所在的传感器节点ID(需与attributes.txt中的节点ID一致)timestamp:对应NetLogo的tick值(整数,从0开始或与模型起始tick匹配)
示例内容:
agent-id,node-id,timestamp 1,1,0 1,2,1 1,3,2 2,5,0 2,5,1 2,4,2
2. 修改模型属性定义
在现有代码中添加以下属性:
walkers-own [ location list-locations carrier? nb-carrier agent-id ;; 新增:智能体唯一ID movement-plan ;; 新增:存储[(timestamp, node-id), ...]格式的移动计划 ] globals [ paths-list walker-movement-data ;; 新增:存储所有智能体的移动数据字典 ]
3. 编写移动数据导入过程
添加读取并整理移动数据的过程:
to import-walker-movements set walker-movement-data make-dictionary file-open "walker-movements.csv" ;; 跳过表头行 file-read-line while [not file-at-end?] [ let line file-read-line let items split line "," let aid read-from-string item 0 items let nid read-from-string item 1 items let ts read-from-string item 2 items ;; 按智能体ID分组存储移动记录 ifelse dictionary-has-key? walker-movement-data aid [ let current-plan dictionary-value walker-movement-data aid set current-plan lput (list ts nid) current-plan set-dictionary-value walker-movement-data aid current-plan ] [ set-dictionary-value walker-movement-data aid (list (list ts nid)) ] ] file-close ;; 对每个智能体的移动计划按时间戳排序 foreach dictionary-keys walker-movement-data [ aid -> let sorted-plan sort-by [a b -> item 0 a < item 0 b] (dictionary-value walker-movement-data aid) set-dictionary-value walker-movement-data aid sorted-plan ] end
4. 修改Setup过程
替换固定创建walkers的逻辑,改为根据导入的数据创建智能体:
to setup clear-all import-network import-walker-movements ;; 新增:导入移动数据 wildlife-nodes ask nodes [ set infected? false ] ;; 根据移动数据创建对应智能体 foreach dictionary-keys walker-movement-data [ aid -> create-walkers 1 [ set shape "arrow" set color yellow set carrier? false set nb-carrier 0 set agent-id aid set movement-plan dictionary-value walker-movement-data aid ;; 设置初始位置为第一个时间戳对应的节点 let initial-record first movement-plan let initial-node get-node item 1 initial-record set location initial-node set list-locations (list initial-node) move-to initial-node ] ] reset-ticks end
5. 修改Go过程中的移动逻辑
替换随机移动代码,改为按导入的移动计划移动:
to go if all? nodes [ infected? ] [ stop ] ask paths [ set thickness 0 ] ask nodes [ infect-walker ] ask walkers [ transmit-disease let current-tick ticks ;; 查找当前tick对应的移动记录 let target-record filter [rec -> item 0 rec = current-tick] movement-plan ifelse length target-record > 0 [ let target-node-id item 1 first target-record let new-location get-node target-node-id ;; 可选:校验目标节点是否与当前节点连通 if member? new-location [path-neighbors] of location [ ask [path-with new-location] of location [ set thickness 0.5 ] face new-location move-to new-location set location new-location set list-locations fput location list-locations ] ] [ ;; 当前tick无记录时保持原位,可根据需求修改 print (word "No movement record for agent " agent-id " at tick " current-tick) ] ] ask wildlifes [ infect-node ] tick end
可选优化
- 插值处理:若移动数据时间戳间隔大于1,可添加逻辑让智能体在tick间平滑移动到目标节点
- 连通性校验:若数据中出现跨非连通节点的跳跃,可选择忽略记录或自动生成路径
- 性能优化:将节点ID与节点的映射缓存到字典中,避免每次查找遍历所有节点
内容的提问来源于stack exchange,提问作者Yerrold
相关产品推荐
相关产品推荐

