NetLogo中实现海龟匹配对应斑块的cum-utility_1值,选择最小化随机数差值的斑块
NetLogo中实现海龟匹配对应斑块的cum-utility_1值,选择最小化随机数差值的斑块
我明白你现在遇到的核心问题了:你给海龟计算了cum-utility_1这个数值列表,但这个列表和对应的学校斑块是脱节的——你只存了数值,没把数值和斑块本身绑定起来,而且NetLogo的主体上下文(海龟/斑块)也搞混了,导致代码报错。
先拆解下你之前的两个错误原因:
- 第一个错误提示“expected input to be a number but got the list”:因为
[cum-utility_1] of myself返回的是海龟的整个累积值列表,不是单个斑块对应的数值,拿列表和随机数做减法自然类型不匹配。 - 第二个错误“can't be run by a patch, only a turtle”:
cum-utility_1是海龟专属变量,斑块根本没有这个变量,你让斑块去计算这个表达式,NetLogo肯定会报错。
下面是具体的解决思路和修改后的代码:
核心思路:把斑块和对应的效用值绑定成配对列表
不要单独存数值列表,而是从一开始就把斑块对象和它的效用值放在同一个列表元素里,这样后续排序、计算累积和的时候,能一直保留斑块的引用,最后直接在海龟上下文里找到匹配的斑块,不用让斑块参与计算。
修改后的完整utility过程
to utility ; 第一步:保存斑块和原始school-utility的配对列表,只保留有效学校 set school-pairs map [p -> list p [school-utility] of p] patches with [schoolachievement_2 > 0] ; 第二步:按原始效用值排序配对列表 set sorted-school-pairs sort-by [[a b] -> item 1 a < item 1 b] school-pairs ; 第三步:计算归一化后的效用值,同时保留斑块引用 let total-util sum map [pair -> item 1 pair] sorted-school-pairs set normalized-pairs map [pair -> list (item 0 pair) (/ (item 1 pair) total-util)] sorted-school-pairs ; 第四步:计算带斑块的累积效用值列表 set cum-pairs [] let sum-so-far 0 foreach normalized-pairs [ let current-patch item 0 ? let current-norm-util item 1 ? set sum-so-far sum-so-far + current-norm-util ; 把斑块和对应的累积值存入列表 set cum-pairs lput (list current-patch sum-so-far) cum-pairs ] ; 第五步:生成随机数,找到差值最小的斑块 let rand-num random-float 1 ; 在cum-pairs里找绝对值差最小的配对 let best-pair min-one-of cum-pairs [abs (rand-num - item 1 ?)] ; 提取最终目标斑块 set target-patch item 0 best-pair end
代码解释
- school-pairs:每个元素是
[斑块对象 原始school-utility值],从根源上把斑块和数值绑定。 - sorted-school-pairs:按原始效用值排序配对列表,保证后续累积和的顺序和你之前的
sort school-utility_1一致。 - normalized-pairs:完成归一化计算,同时保留斑块引用。
- cum-pairs:最终的累积值配对列表,每个元素是
[斑块对象 对应累积效用值],这一步彻底解决了数值和斑块脱节的问题。 - 选择目标斑块:直接在海龟上下文里遍历
cum-pairs,用min-one-of找到差值最小的配对,再提取斑块对象即可,完全不需要让斑块执行任何依赖海龟变量的计算。
这样修改后,你就能实现让海龟选择到符合要求的学校斑块了。
备注:内容来源于stack exchange,提问作者Nicola Pensiero
相关产品推荐
相关产品推荐

