基于nw扩展的Louvain社区链路权重分配优化需求
为Louvain社区内/外链路分配权重的优化实现
我使用nw扩展生成了偏好依附(preferential-attachment)网络,需要为链路分配不同权重:同一nw:louvain-communities社区内的海龟间链路权重设为2,跨社区的链路权重设为1。
最初的错误实现
最初编写的代码如下,但会导致所有链路权重都被设为2,不符合预期:
links-own [weight] turtles-own [ community ] nw:set-context turtles links ask turtles [ ask my-links [ if member? other-end nw:louvain-communities [ set weight 1 ] ask other links [set weight 2] ] ]
错误原因
这段代码逻辑混乱:ask other links中的other指代链路的另一端海龟,执行后会操作该海龟的所有链路,直接覆盖了之前设置的权重,最终所有链路都被设为2。
可行但繁琐的实现
参考社区着色代码修改后,以下代码能满足需求,但逻辑冗余、不够简洁:
to weight-clusters [ clusters ] ask links [ set weight 1 ] 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 [ ask my-links [ if member? other-end cluster [ set weight 2 ] ] ] ]) end
优化后的简洁实现
方案1:利用社区ID直接判断
通过nw:module-id直接获取海龟的社区ID,让每条链路自行判断两端是否同属一个社区,代码更简洁高效:
links-own [weight] turtles-own [community] to setup-link-weights ; 为每个海龟分配所属Louvain社区的ID nw:set-context turtles links ask turtles [ set community nw:module-id ] ; 每条链路根据两端社区是否一致设置权重 ask links [ set weight ifelse-value ([community] of end1 = [community] of end2) [2] [1] ] end
方案2:遍历社区批量设置
如果需要保留社区遍历的逻辑,可以简化掉无关的着色代码,只保留权重设置逻辑:
links-own [weight] to setup-link-weights nw:set-context turtles links ; 默认所有链路设为跨社区权重1 ask links [ set weight 1 ] ; 遍历每个Louvain社区,将社区内的链路权重设为2 foreach nw:louvain-communities [ cluster -> ask cluster [ ask my-links with [member? other-end cluster] [ set weight 2 ] ] ] end
这两种方案都能实现需求,且逻辑清晰、代码简洁,避免了冗余操作。
内容的提问来源于stack exchange,提问作者Dietrich Bepan
相关产品推荐
相关产品推荐

