NetLogo如何结合rnd:weighted-one-of-list更新列表对应索引值?
实现方案
现有代码与需求
当前的初始定义代码:
set startingcharact (list pricered qualityred innovationred sustainabred) set probs-impr-red [[1 0.1] [1 0.1] [1 0.3] [1 0.5]]
要实现的逻辑:调用rnd扩展的rnd:weighted-one-of-list按给定权重抽取对应项,给startingcharact列表同索引位置的值加1,比如抽中第一项就给pricered加1。
之前尝试的写法会触发报错:
; 错误写法:直接将单个抽取值和全列表做求和运算,类型不匹配 set startingcharact (map + startingcharact first rnd:weighted-one-of-list probs-impr-red last)
报错原因
rnd:weighted-one-of-list的返回值是权重列表里被抽中的单个子列表(比如抽中第一项返回[1 0.1]),原写法没有生成和原特征列表等长的、仅选中位置为1其余位置为0的掩码数组,直接拿单个值和长度为4的列表做map逐元运算,会触发参数长度/类型不匹配的错误。
可直接运行的正确写法
推荐用replace-item实现,逻辑清晰性能更好:
; 按权重抽取对应子列表 let selected-item rnd:weighted-one-of-list probs-impr-red [pair -> last pair] ; 定位抽中子列表在权重配置里的索引 let selected-index position selected-item probs-impr-red ; 给原特征列表对应索引位置的值+1 set startingcharact replace-item selected-index startingcharact (item selected-index startingcharact + 1)
如果偏好map写法,也可以用逐元判断的方式实现:
let selected-index position (rnd:weighted-one-of-list probs-impr-red [pair -> last pair]) probs-impr-red set startingcharact map [ [current-val idx] -> ifelse-value (idx = selected-index) [current-val + 1] [current-val] ] startingcharact range length startingcharact
注意:调用
rnd:weighted-one-of-list时必须传入提取权重的reporter过程,也就是示例里的[pair -> last pair],作用是取每个权重子列表的第二个元素作为概率权重,漏写这部分也会触发语法报错。
内容的提问来源于stack exchange,提问作者Delu
相关产品推荐
相关产品推荐

