NetLogo囚徒困境模型代理出生死亡时交互历史列表运行报错求助
问题原因与修复方案
错误根源
- NetLogo的
turtle全局编号who为自增不回收规则:代理死亡后who编号不会被新孵化的代理复用,新代理who编号只会持续增大,和当前存活代理总数无直接关联 - 你当前的交互历史列表
partner-history-com长度按当前存活代理总数生成,当新代理孵化后who编号超过列表最大索引,调用item/replace-item访问对应who的历史记录时就会触发索引越界报错 - 额外问题:你在
hatch新代理时没有初始化partner-history-com属性,新代理的历史列表为空也会直接报错
修复方案
这里提供两种可直接落地的修改方式,推荐优先使用第一种:
方案1:使用Table扩展存储交互历史(推荐)
该方案无需关心索引边界,性能更稳定:
- 代码首行添加扩展声明:
extensions [table]
- 修改
setup-history-lists-com过程:
to setup-history-lists-com ask companies [ ; 用table存储,键为交互伙伴的who号,值为是否背叛 set partner-history-com table:make ] end
- 修改策略读取历史的逻辑(以
tit-for-tat-com为例,unforgiving-com同步修改):
to tit-for-tat-com set num-tit-for-tat-com-games num-tit-for-tat-com-games + 1 let partner-who [who] of partner-com ; 没有历史记录默认对方没有背叛 set partner-defected?-com ifelse-value (table:has-key? partner-history-com partner-who) [ table:get partner-history-com partner-who ] [ false ] ifelse (partner-defected?-com) [set defect-now?-com true] [set defect-now?-com false] ; 后面原有逻辑保持不变 ... end
- 修改历史更新逻辑(以
tit-for-tat-com-history-update为例,unforgiving-com-history-update同步修改):
to tit-for-tat-com-history-update let partner-who [who] of partner-com table:put partner-history-com partner-who partner-defected?-com end
方案2:调整列表长度适配who编号
如果你不想使用扩展,可直接修改列表生成逻辑:
修改setup-history-lists-com过程的重复次数为当前最大who号+1,保证所有存活代理的who号都在索引范围内:
to setup-history-lists-com set num-companies (count companies) let default-history-com [] ; 用最大who号+1作为列表长度,而不是count companies repeat (max [who] of companies + 1) [ set default-history-com (fput false default-history-com) ] ask companies [ set partner-history-com default-history-com ] end
同时补充新孵化代理的属性初始化,在birth-die-com的hatch代码块添加历史列表初始化:
; 以tit-for-tat-com的hatch为例,unforgiving-com同步修改 hatch 1 [ set earnings-tit-for-tat-com random 2 + 1 ; 新增:同步初始化其他公共属性 set shape "pentagon" set size 1.3 set tit-for-tat-com-score-round 0 set unforgiving-com-score-round 0 set score-com 0 set partnered?-com false set partner-com nobody setxy random-xcor random-ycor ]
额外优化建议
- 你当前每tick都会重置所有代理的交互历史,相当于之前的交互记录全部失效,不符合以牙还牙、零容忍策略的设计逻辑,可根据需求调整为仅给新出生的代理初始化空历史,存量代理保留历史记录
- 资源计算逻辑中不要在策略过程里重复ask同范围的patches和companies,避免重复计算消耗性能
内容的提问来源于stack exchange,提问作者ANGELA1518
相关产品推荐
相关产品推荐

