【发布时间】:2021-09-18 01:39:44
【问题描述】:
我有一个包含 4,000 多个节点的网络,并且我有一个边列表(节点对之间的连接)。所有节点都应该收敛到一个中心点,但我无法对节点进行排序,因为它们没有以重新排序可行的方式编号或标记。
我需要什么?:根据附上的小例子,我需要所有的节点都指向节点F(所有节点都可以到达F),这样无向图就变成了有向图( DAG) 并且作为 限制,每个节点对之间只有一条边。当且仅当要删除循环(例如 A -> B,B
我拥有的是这样的:
library(igraph)
library(tidygraph)
library(ggraph)
library(tidyverse)
# edge list
edgelist <- tribble(
~from, ~to,
"A", "B",
"A", "C",
"B", "D",
"C", "D",
"C", "E",
"D", "E",
"D", "F")
# create the graph
g <- as_tbl_graph(edgelist)
# undirected graph
g %>%
ggraph(layout = "graphopt") +
geom_edge_link() +
geom_node_point(shape = 21, size = 18, fill = 'white') +
geom_node_text(aes(label = name), size = 3) +
theme_graph()
这是我提出的排序过程,以便边列表成为 DAG:
s <- names(V(g))
# define node objective
target <- "F"
# exclude target from vertex list
vertex_list <- s[s != target]
# calculate the simple path of each node to the destination node (target)
route_list <- map(vertex_list, ~ all_simple_paths(graph = g,
from = .x,
to = target)) %>%
set_names(vertex_list) %>%
map(~ map(., ~ names(.x))) %>%
flatten() %>%
map(~ str_c(.x, collapse = ","))
# generate the list of ordered edges
ordered_edges <- do.call(rbind, route_list) %>%
as.data.frame(row.names = F) %>%
set_names("chain") %>%
group_by(chain) %>%
summarise(destination = str_split(chain, ","), .groups = "drop") %>%
mutate(
from = map(destination, ~ lag(.x)) %>%
map(~ .x[!is.na(.x)]),
to = map(destination, ~ lead(.x)) %>%
map(~ .x[!is.na(.x)]),
) %>%
select(from, to) %>%
unnest(cols = everything()) %>%
group_by(across(everything())) %>%
summarise(enlaces = n(), .groups = "drop") %>%
select(-enlaces)
警告:当节点数达到一定大小(比如 90 个)时,该算法会生成使图非循环的循环,因此我要做的一个附加过程是应用一个函数在 Python 中调用 feedback_arc_set 来删除将使图成为 DAG 的边。
为简单起见,我没有包含删除这些循环所需的代码,因为在这个特定示例中没有生成循环。
# draw the graph again
as_tbl_graph(ordered_edges) %>%
ggraph(layout = "graphopt") +
geom_edge_link(arrow = arrow(length = unit(3, 'mm'),
type = "closed",
angle = 30),
end_cap = circle(7, 'mm')) +
geom_node_point(shape = 21, size = 18, fill = 'white') +
geom_node_text(aes(label = name), size = 3) +
theme_graph()
由reprex package (v2.0.0) 于 2021-07-07 创建
那么有什么问题?:节点数大于2000时算法的复杂度
如果我尝试使用 2000 个节点来执行此操作,则算法永远不会结束。我让它运行了 24 小时,但没有完成。事实上,我没有找到一种方法来知道它是否有效。在这个place我发现{igraph}all_simple_paths的函数在后台使用了DFS,但是复杂度是O (|V|!) where |V|是顶点数,|V|!是顶点数的阶乘。
有没有办法降低复杂度?
【问题讨论】:
-
“我需要所有节点都指向节点 F”猜你的意思是“F 可以从所有节点到达”?
-
@ravenspoint。我编辑了我的问题以澄清你提到的内容。答案是是的你指出的一切。
标签: r time-complexity igraph graph-theory tidygraph