如何在不在 igraph 中创建重复边的情况下生成基于随机属性的边?
How to generate a random attribute based edge without creating a duplicate edge in igraph?
我目前有这样的代码:
g <- erdos.renyi.game(30, 151 , type = "gnm" , directed = F , loops = F)%>%
set_vertex_attr("a", value = 0)
V(g)$a <- sample(c(0, 1), vcount(g), replace = TRUE, prob = c(.25, .75))
g <- add_edges(g,c(sample(V(g)[V(g)$a==0],1), sample(V(g)[V(g)$a == 1], 1)))
我正在尝试根据属性值生成随机的新边。然而,目前由于图中边的密度很高,很多时候生成的边是重复的。如何修改最后一行代码,使其不生成重复边?
一种方法是找出哪些节点对之间没有边,然后从这些节点对中随机抽样。下面的代码可以打包成一个函数,这样你就可以连续地随机添加新的边。
library(purrr) # For map function
# Create graph reproducibly
set.seed(54)
g <- erdos.renyi.game(30, 151 , type = "gnm" , directed = F , loops = F) %>%
set_vertex_attr("a", value = 0)
V(g)$a <- sample(c(0, 1), vcount(g), replace = TRUE, prob = c(.25, .75))
# List all possible pairs of nodes
all_pairs = apply(combn(1:vcount(g), 2), 2, paste, collapse="-")
# List all pairs of nodes with edges between them
current_pairs = apply(get.edgelist(g), 1, paste, collapse="-")
# List all pairs of nodes with no edge between them
eligible_pairs = setdiff(all_pairs, current_pairs)
# Get indices of eligible pairs with desired attribute a criteria
attr_select = map_lgl(strsplit(eligible_pairs, "-"), function(p) {
(p[1] %in% V(g)[V(g)$a==0] & p[2] %in% V(g)[V(g)$a==1]) |
(p[1] %in% V(g)[V(g)$a==1] & p[2] %in% V(g)[V(g)$a==0])
})
# Keep only those pairs that meet the attribute a condition above
eligible_pairs = eligible_pairs[attr_select]
# Add an edge at random between two nodes that don't currently have an edge between them
# and that meet the attribute a criteria
set.seed(10) # This is just for reproducibility of this example. Remove this if you want a different pair selected each time in your actual use case.
new_edge = unlist(strsplit(sample(eligible_pairs, 1), "-"))
g <- add_edges(g, new_edge)
我目前有这样的代码:
g <- erdos.renyi.game(30, 151 , type = "gnm" , directed = F , loops = F)%>%
set_vertex_attr("a", value = 0)
V(g)$a <- sample(c(0, 1), vcount(g), replace = TRUE, prob = c(.25, .75))
g <- add_edges(g,c(sample(V(g)[V(g)$a==0],1), sample(V(g)[V(g)$a == 1], 1)))
我正在尝试根据属性值生成随机的新边。然而,目前由于图中边的密度很高,很多时候生成的边是重复的。如何修改最后一行代码,使其不生成重复边?
一种方法是找出哪些节点对之间没有边,然后从这些节点对中随机抽样。下面的代码可以打包成一个函数,这样你就可以连续地随机添加新的边。
library(purrr) # For map function
# Create graph reproducibly
set.seed(54)
g <- erdos.renyi.game(30, 151 , type = "gnm" , directed = F , loops = F) %>%
set_vertex_attr("a", value = 0)
V(g)$a <- sample(c(0, 1), vcount(g), replace = TRUE, prob = c(.25, .75))
# List all possible pairs of nodes
all_pairs = apply(combn(1:vcount(g), 2), 2, paste, collapse="-")
# List all pairs of nodes with edges between them
current_pairs = apply(get.edgelist(g), 1, paste, collapse="-")
# List all pairs of nodes with no edge between them
eligible_pairs = setdiff(all_pairs, current_pairs)
# Get indices of eligible pairs with desired attribute a criteria
attr_select = map_lgl(strsplit(eligible_pairs, "-"), function(p) {
(p[1] %in% V(g)[V(g)$a==0] & p[2] %in% V(g)[V(g)$a==1]) |
(p[1] %in% V(g)[V(g)$a==1] & p[2] %in% V(g)[V(g)$a==0])
})
# Keep only those pairs that meet the attribute a condition above
eligible_pairs = eligible_pairs[attr_select]
# Add an edge at random between two nodes that don't currently have an edge between them
# and that meet the attribute a criteria
set.seed(10) # This is just for reproducibility of this example. Remove this if you want a different pair selected each time in your actual use case.
new_edge = unlist(strsplit(sample(eligible_pairs, 1), "-"))
g <- add_edges(g, new_edge)