如何编写R代码实现任意不相交子图间的边重连?
问题描述
我有一些可通过如下方式生成的(图边)数据:
data.gen = function(g,n){ m = (length(g)-1)*n gm = rep(g,each=m) x = data.frame(g=gm,v1=paste0(gm,1,seq(m)),v2=paste0(gm,2,seq(m))) }
例如,data.gen(c('a','b','c'),1) 生成的结果为:
g v1 v2 a a11 a21 a a12 a22 b b11 b21 b b12 b22 c c11 c21 c c12 c22
我希望重新分配(重排)v2列的数据,使每个分组g的所有值最终都对应到不同分组的行中。背景是我需要重连不相交子图(相互连通的独立节点“岛”)之间的随机数量边。上述示例中的一种可行结果如下:
g v1 v2 a a11 b21 a a12 c21 b b11 a21 b b12 c22 c c11 a22 c c12 b22
n的含义是每对子图之间的连接边数。请问如何针对任意g和n编写代码实现该功能?
解决方案
实现思路
- 按分组
g提取所有v2节点,整理成分组集合 - 对每个分组,筛选出其他所有分组的
v2节点 - 从非自身分组的节点集合中随机抽取对应数量的节点,替换当前分组的
v2列
代码实现
reassign_v2 <- function(df) { # 按分组拆分v2节点 v2_groups <- split(df$v2, df$g) group_names <- unique(df$g) # 为每个分组重新分配v2 df$v2 <- unlist(lapply(group_names, function(current_group) { # 获取当前分组需要替换的行数 row_count <- nrow(df[df$g == current_group, ]) # 收集所有非当前分组的v2节点 non_self_v2 <- unlist(v2_groups[group_names != current_group]) # 随机抽取对应数量的节点 sample(non_self_v2, row_count) })) return(df) } # 测试用例 test_df <- data.gen(c('a','b','c'), 1) result <- reassign_v2(test_df) print(result)
逻辑验证
原始数据中每个分组的行数为(length(g)-1)*n,而其他所有分组的v2节点总数恰好是(length(g)-1)个分组 × n个节点 = (length(g)-1)*n,因此随机抽取时能保证每个分组的v2节点全部来自其他分组,且每对子图之间的边数符合n的设定。
内容的提问来源于stack exchange,提问作者jessexknight
相关产品推荐
相关产品推荐

