NetLogo按patch的district属性计算分区获胜turtle变量方法
NetLogo按斑块分区统计政党得票获胜者实现方案
需求说明
- 斑块(patch)存在两个属性:取值范围0-100的分区编号
district、票数votes - 海龟主体为政党(
party),距离斑块最近的政党获得该斑块的票数 - 需要针对每个
district分区,统计该分区内所有政党的得票总数,标记出得票最高的政党作为该分区获胜者,存入指定变量 - 现有逻辑已经实现全图范围的斑块-最近政党匹配、政党全图总票数统计,但无法按分区维度完成统计,之前编写的
foreach、sort-by逻辑均存在运行错误
已验证可用的基础代码
to update-support ask patches [set closest-party min-one-of parties [distance myself]] ;; 为每个斑块匹配距离最近的政党 ask parties [set mysize sum [votes] of patches with [closest-party = myself]] ;; 统计每个政党在全图获得的总票数 end
之前的错误尝试代码
第一次尝试
to update support ask patches [ set closest-party min-one-of parties [distance myself] ;;patches find their closest party set closest-party-list [ (list closest-party) ] of patches (foreach district-number [set district-vote-map map [ifelse-value (? != district) [? = district] [?]] closest- party-list]) ;;and then link this closest-party-list to some code for asking parties?? ] ] end
第二次尝试
to update support ask patches [ set closest-party min-one-of parties [distance myself]] ;;patches find their closest party ask parties [ set district-vote [ (foreach [(district) of patches] sum [votes] of patches with [closest-party = myself] and [district = [?]])] end
正确实现逻辑
之前代码报错的核心原因是遍历顺序错误:不需要在斑块的遍历循环里嵌套分区统计,直接遍历所有分区编号,在单个分区的范围内筛选斑块、统计各政党得票即可,不需要复杂的嵌套列表映射。
完整可运行代码如下,可根据自己的变量存储需求调整:
; 代码开头需要提前声明对应变量,根据自己的存储需求选择即可 ; 如果用全局表存储分区-获胜者映射,加这两行 extensions [table] globals [district-winner-table] ; 如果要给政党自身存储获胜分区列表,在breed声明里加own属性 ; breed [parties party] ; parties-own [mysize won-districts] to update-support ;; 原有基础逻辑 ask patches [set closest-party min-one-of parties [distance myself]] ask parties [set mysize sum [votes] of patches with [closest-party = myself]] ;; 初始化存储结构,每次更新前清空旧数据 set district-winner-table table:make ask parties [set won-districts []] ;; 遍历所有0-100的分区编号 foreach (range 0 101) [ d -> ; 筛选当前分区内的所有斑块 let current-district-patches patches with [district = d] ; 跳过不存在斑块的空分区 if any? current-district-patches [ ; 找出当前分区内得票最高的政党 let winner max-one-of parties [ sum [votes] of current-district-patches with [closest-party = myself] ] ; 存储结果,两种方式可同时使用 ; 1. 存入全局表,后续可直接通过分区号查询获胜者 table:put district-winner-table d winner ; 2. 给获胜政党添加该分区的获胜标记 ask winner [set won-districts lput d won-districts] ] ] end
补充说明
- 若需要处理同票情况,可在
max-one-of逻辑后追加判断,比如平票时随机选择获胜者、按政党固定编号排序选择,避免出现无返回值的异常 - 如果不想用
table扩展,也可以用列表存储[分区号, 获胜者]的键值对,只是查询效率比table低,适合分区数量少的场景 - 不需要额外给patch新增多余变量,所有统计都基于已经计算好的
closest-party属性完成,性能更高
内容的提问来源于stack exchange,提问作者San88
相关产品推荐
相关产品推荐

