NetLogo社区聚类点击簇显示海龟编号代码调试
原代码无效原因
- 类型不匹配:
nw:louvain-communities返回值是海龟代理集合构成的列表,原代码用member?判断单个海龟的who数值是否在列表中,条件永远为假,不会触发后续逻辑。 - 逻辑错误:就算条件触发,原代码是给所有海龟设置标签,不是仅显示被点击簇的海龟。
- 触发逻辑问题:普通按钮点击仅单次执行,无法持续监听鼠标状态;且每次调用
nw:louvain-communities都会重新计算社区划分,不仅效率低,还可能和之前着色的社区结果不一致。
方案1:点击簇浮动显示编号(自动避免重叠)
首先在代码顶部声明全局变量,用于存储固定的社区划分结果:
globals [ all-clusters ; 存储鲁汶算法计算得到的所有社区簇 ]
修改原有社区检测过程,将计算结果存入全局变量,避免重复计算:
to community-detection nw:set-context turtles links set all-clusters nw:louvain-communities color-clusters all-clusters end to color-clusters [ clusters ] ; 重置所有颜色 ask turtles [ set color gray - 3 ] ask links [ set color gray - 3 ] let n length clusters let colors ifelse-value (n <= 12) [ n-of n remove gray remove white base-colors ] ;; 选择除白、灰外的基础色 [ n-values n [ approximate-hsb (random 255) 255 (100 + random 100) ] ] ; 簇数量过多时生成随机色 ; 遍历簇和对应颜色逐个赋值 (foreach clusters colors [ [cluster cluster-color] -> ask cluster [ set color cluster-color ; 同簇链接设置为比节点色稍暗的同色系 ask my-links [ set color cluster-color - 1 ] ] ]) end
新增点击检测与标签显示过程,将该过程放入持续运行的go循环中即可实时响应鼠标操作:
to detect-cluster-click ; 左键点击簇内海龟时显示对应簇的所有编号 if mouse-down? and mouse-button = "left" [ let clicked-turtle one-of turtles at-point mouse-xcor mouse-ycor if is-turtle? clicked-turtle [ ; 定位被点击海龟所属的簇 let target-cluster first filter [cluster -> member? clicked-turtle cluster] all-clusters ; 先清空所有已有标签 ask turtles [set label ""] ; 逐个给簇内海龟加标签,自动偏移位置避免重叠 let label-idx 0 ask target-cluster [ set label who set label-color color ; 按索引偏移标签位置,横纵错开,可根据节点大小调整偏移数值 set label-offset (list (0.3 + (label-idx mod 3) * 0.25) (0.3 + floor(label-idx / 3) * 0.25)) set label-idx label-idx + 1 ] ] ] ; 右键点击空白区域清空所有标签 if mouse-down? and mouse-button = "right" [ let clicked-turtle one-of turtles at-point mouse-xcor mouse-ycor if not is-turtle? clicked-turtle [ask turtles [set label ""]] ] end
方案2:监视器显示(实现最简单)
如果不需要浮动标签,用监视器显示更稳定:
- 在全局变量中新增
selected-cluster-ids,用于存储当前选中簇的海龟编号列表。 - 将方案1中
detect-cluster-click过程里给海龟设置标签的代码,替换为set selected-cluster-ids sort [who] of target-cluster。 - 在NetLogo界面添加一个监视器组件,将监视器的报告者设置为
selected-cluster-ids,点击任意簇时监视器就会自动输出该簇所有海龟的编号。
如果需要通过观察者命令直接查询指定簇的海龟,在命令中心执行对应代码即可:
; 查询索引为0的簇内所有海龟的who编号(运行community-detection后生效) print [who] of item 0 all-clusters ; 查询who编号为5的海龟所在簇的所有成员编号 let target-turtle turtle 5 print sort [who] of first filter [cluster -> member? target-turtle cluster] all-clusters
内容的提问来源于stack exchange,提问作者razimbres
相关产品推荐
相关产品推荐

