[英]Connecting Two Random Nodes in a Directed Acyclic Weighted Graph
Summary概括
So I have a directed acyclic weighted graph where each edge has an input and output node, each node has an ID and I use a dictionary to map all ingoing edges to one node by its ID and another to do the same for all outgoing edges so when presented a node ID I can tell all ingoing and outgoing edges in ~O(1) time.所以我有一个有向无环加权图,其中每条边都有一个输入和输出节点,每个节点都有一个 ID,我使用字典将所有传入边通过其 ID 映射到一个节点,另一个对所有传出边执行相同操作当呈现节点 ID 时,我可以在 ~O(1) 时间内告诉所有传入和传出边缘。
Requirement要求
I need to be able to add new random edges (ie connect two random nodes) in a way where it is guaranteed that no matter how big the graph is it wont be having any cycles.我需要能够以一种方式添加新的随机边(即连接两个随机节点),以保证无论图形有多大,它都不会有任何循环。
What I tried我试过的
Since I'm in full control of how to build my graph I could sort it topologically and use Kahn's Algorithm to figure if for two uniformly randomly chosen nodes N1 and N2 the graph will result in a cycle in O(n) time.由于我可以完全控制如何构建我的图,我可以对其进行拓扑排序并使用卡恩算法来确定对于两个均匀随机选择的节点 N1 和 N2,该图是否会导致 O(n) 时间的循环。 The problem with that is what if it does?
问题是如果这样做呢? I'd have to try a new random pair and repeat the process until I get lucky.
我必须尝试一个新的随机对并重复这个过程,直到我幸运为止。 This sounds as if it will scale really badly with the graph since the more edge dense the graph is the more likely it is that a new random one will create a cycle.
这听起来好像它会随着图的缩放非常糟糕,因为图的边越密,新的随机图就越有可能创建一个循环。
I have also read this post: Generating a random DAG , which is similar in nature to my problem, however, I can't use the suggested solution to connect nodes based on their IDs and only connect smaller to larger IDs (nodes that came before with nodes that are new) due to other constraints that I have on the problem.我还阅读了这篇文章: 生成随机 DAG ,这在本质上与我的问题相似,但是,我无法使用建议的解决方案根据节点的 ID 连接节点,只能将较小的 ID 连接到较大的 ID(之前出现的节点)节点是新的)由于我对问题的其他限制。
Question题
Is there a way to design a structure that will only ever allow me to randomly pick between nodes none of which, if connected through a new edge, will yield a cycle irrelevant of the memory overhead?有没有办法设计一种结构,它只允许我在节点之间随机选择,如果通过新的边连接,没有一个节点会产生与内存开销无关的循环? This should then be an O(1) operation.
这应该是一个 O(1) 操作。
I have an O(1) solution for the check if an edge can be included in the graph.我有一个O(1)解决方案来检查图中是否可以包含一条边。 However it will take you worst-case O(n) to insert the edge.
但是,插入边缘需要最坏情况的O(n) 。
You could maintain a binary reachability matrix R
where R[u, v]=1
if you can reach v
from u
in your current graph and R[u, v]=0
if not.您可以维护一个二元可达性矩阵
R
,其中R[u, v]=1
如果您可以从当前图中的u
到达v
,否则R[u, v]=0
。 R
can be computed once using Floyd-Warshall . R
可以使用Floyd-Warshall计算一次。
If you want to check if you can include an edge (u,v)
you now just have to check if R[v, u] = 0
.如果您想检查是否可以包含边
(u,v)
您现在只需检查是否R[v, u] = 0
。 If it is R[v, u] = 1
you are constructing a circle by inserting (u,v)
.如果它是
R[v, u] = 1
您正在通过插入(u,v)
构建一个圆。
The remaining problem becomes updating this structure.剩下的问题就是更新这个结构。 If you end up inserting the edge
(u, v)
into the graph you will set R[u, v] = 1
.如果您最终将边
(u, v)
插入图中,您将设置R[u, v] = 1
。 Additionally, all nodes that were able to reach u
( R[:,u]=1
) are are now able to reach all nodes reachable by v
( R[v,:] = 1
).此外,所有能够到达
u
( R[:,u]=1
) 的节点现在都能够到达v
( R[v,:] = 1
) 所能到达的所有节点。 Thus you will need to set your entries R[i, j] = 1
if R[i,u] = 1
and R[v:j] = 1
.因此
R[i, j] = 1
如果R[i,u] = 1
和R[v:j] = 1
R[i, j] = 1
您将需要设置您的条目R[i, j] = 1
R[v:j] = 1
。
Unfortunately, the update step will take O(n) in the worst case不幸的是,在最坏的情况下,更新步骤将花费 O(n)
If you want to select a possible edge at random, you will have to additionally maintain and update a list of possible edges through the same structure.如果要随机选择一条可能的边,则必须另外维护和更新通过相同结构的可能边列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.