我有一个DAG。我有一个操作,用于在两个节点之间添加边。
如果B可以从A到达,则B是A的父节点。如果B可以直接从A到达(不经过其他节点),则B是A的直接父节点。
该图的要求如下:
1.没有循环。 2.对于任何节点,都有一组直接父节点P [1],P [2],P [3]… P [i]不是P [j]的父节点,其中i和j都是任意整数。
如果添加一条边,则不符合要求1,则不构造该边。如果添加一条边,则不符合要求2,但将以满足要求2的方式修改直接父节点。
例如,有3个节点
A,直接父节点:无 B,直接父节点:A C,直接父节点:A
现在,如果我在B和C之间添加一条边,则我们有
C,直接父节点:A,B
但是A是B的父节点,不符合要求2,因此从C的直接父节点中删除A,并且我们有
C,直接父节点:B
目前这是我所做的: 从A到B添加边缘(这个A成为B的父节点)
检查B是否是A的父节点。如果是,则不添加边缘。(这确保了没有循环) 通过BFS检查A是否已经是B的父节点。如果是,则不添加边缘。 查找A的父节点与B的直接父节点的交集。通过BFS查找A的每个父节点来完成此操作。从B的直接父节点中删除交集,并将A添加为B的直接父节点。
这很慢。它在5k节点级别崩溃(我希望它处理少于100k节点的任何图形),速度变得不可接受,添加节点边缘需要0.02秒。
我有一种感觉,步骤1和2可以使用其他算法在1步中完成。
我考虑使用拓扑排序,但必须遍历整个图形,这是我的步骤1和2的最坏情况。当添加新节点时,排序将被破坏。因此,我必须为插入运行拓扑排序,以便它不会产生任何好处。对于步骤3,必须找到A的所有父节点。该过程相当缓慢,因为平均而言,它要遍历图形的相当一部分。
如何使其更有效?
如果B可以从A到达,则B是A的父节点。如果B可以直接从A到达(不经过其他节点),则B是A的直接父节点。
该图的要求如下:
1.没有循环。 2.对于任何节点,都有一组直接父节点P [1],P [2],P [3]… P [i]不是P [j]的父节点,其中i和j都是任意整数。
如果添加一条边,则不符合要求1,则不构造该边。如果添加一条边,则不符合要求2,但将以满足要求2的方式修改直接父节点。
例如,有3个节点
A,直接父节点:无 B,直接父节点:A C,直接父节点:A
现在,如果我在B和C之间添加一条边,则我们有
C,直接父节点:A,B
但是A是B的父节点,不符合要求2,因此从C的直接父节点中删除A,并且我们有
C,直接父节点:B
目前这是我所做的: 从A到B添加边缘(这个A成为B的父节点)
检查B是否是A的父节点。如果是,则不添加边缘。(这确保了没有循环) 通过BFS检查A是否已经是B的父节点。如果是,则不添加边缘。 查找A的父节点与B的直接父节点的交集。通过BFS查找A的每个父节点来完成此操作。从B的直接父节点中删除交集,并将A添加为B的直接父节点。
这很慢。它在5k节点级别崩溃(我希望它处理少于100k节点的任何图形),速度变得不可接受,添加节点边缘需要0.02秒。
我有一种感觉,步骤1和2可以使用其他算法在1步中完成。
我考虑使用拓扑排序,但必须遍历整个图形,这是我的步骤1和2的最坏情况。当添加新节点时,排序将被破坏。因此,我必须为插入运行拓扑排序,以便它不会产生任何好处。对于步骤3,必须找到A的所有父节点。该过程相当缓慢,因为平均而言,它要遍历图形的相当一部分。
如何使其更有效?