Javascript 在寻找最长路径时消除有向无环图中的无关边
我问了一个关于在数量可变的集合中查找没有重复字符的子序列的问题。解决方案是创建一个每对字母的矩阵,丢弃在每个集合中没有出现的字母,然后在有向无环图中找到对应的字母。但是,我不想要最长的路径,我想要几个最长的路径(例如,如果它生成长度为10、10、9、8、8、3、3、2和1的子序列,我可能只想显示前5个子序列) 因此,由于我不是只寻找最长路径,为了生成结果子序列,而不是使用wikipedia文章中描述的最长路径算法,我使用的是一种简单的算法,它只生成所有可能子序列的列表。这将生成一组类似于我上一个问题的结果 问题是我想减少它生成的子序列的数量 例如,如果我有以下集合:Javascript 在寻找最长路径时消除有向无环图中的无关边,javascript,algorithm,graph,directed-acyclic-graphs,Javascript,Algorithm,Graph,Directed Acyclic Graphs,我问了一个关于在数量可变的集合中查找没有重复字符的子序列的问题。解决方案是创建一个每对字母的矩阵,丢弃在每个集合中没有出现的字母,然后在有向无环图中找到对应的字母。但是,我不想要最长的路径,我想要几个最长的路径(例如,如果它生成长度为10、10、9、8、8、3、3、2和1的子序列,我可能只想显示前5个子序列) 因此,由于我不是只寻找最长路径,为了生成结果子序列,而不是使用wikipedia文章中描述的最长路径算法,我使用的是一种简单的算法,它只生成所有可能子序列的列表。这将生成一组类似于我上一个
A = AB12034
B = BA01234
C = AB01234
。。。我的算法目前将在每个集合中产生以下对:
A - 1 B - 1 1 - 2 2 - 3 0 - 3 3 - 4
2 2 3 4 4
3 3 4
4 4
0 0
这在技术上是正确的,但我想消除其中的一些对。例如,请注意,2
总是在1
之后。因此,我想消除A2
和B2
对(即A
和B
不应直接跳到2
…它们应始终先通过1
)。此外,1
不应跳转到除2
之外的任何数字,因为2
总是紧跟在它之后。此外,请注意0
总是出现在B
和3
之间,因此我想消除这对B3
(同样,B
在跳转到3
之前应该始终通过0
,因为所有集合都有这三个字母的位置:B<0<3
)
为了清楚起见,当前算法将给出以下子序列:(为了简洁起见,我只包括以A
开头的子序列):
。。。所有标有*
的标记都应删除
生成所需子序列的(正确)对为:
A - 1 B - 1 1 - 2 2 - 3 0 - 3 3 - 4
0 0
A1234
A034
B1234
B034
1234
234
034
34
。。。子序列的完整列表为:
A - 1 B - 1 1 - 2 2 - 3 0 - 3 3 - 4
0 0
A1234
A034
B1234
B034
1234
234
034
34
换句话说,我试图从这个有向无环图出发:
为此:
我应该使用什么样的算法/逻辑来消除这些无关的对(即图边)?或者你认为我首先生成成对的逻辑应该改变吗
此外,请注意0总是出现在B和3之间,因此我想消除对B3(同样,B在跳到3之前应该始终通过0,因为所有集合都有这三个字母的位置:B<0<3)
嗯,好的,那么如果所有集合上的n0
保持不变,那么移除所有(n0,n2)
对?这可以通过以下方式实现(在伪Python中):
容易就是容易。如果图形不是太大,它可能也足够有效
- 对于每个节点(从没有传入边的节点开始),遵循所有路径,标记距离,将所有直接子节点标记为1,并将它们放入队列中。当队列不为空时,拉出一个节点
,让n
作为其从起点的距离。查看其所有直接子级,如果有标记为1的子级,则从开始到结束移除边缘,将d
的所有子级放入标记为距离n
的队列中。从队列中拉出下一个节点d+1
Jsprenkn0wn所说的,只是有一点更详细。由于该图是非循环的,一个可能的解决方案是应用您最喜欢的最短路径算法(Bellman frod、Floyd Warshal等),但比较条件发生了变化(以便长路径胜过短路径)。如果我理解正确,您需要最大公共子序列,因此在图中要消除两个节点之间存在较长路径的边?@DanielFischer:正是。。。有没有一种简单/有效的方法可以做到这一点?我应该首先按照拓扑顺序对图进行排序吗?为了澄清——您是想要一个未加权的DAG中的所有最长路径,还是对较短的路径也感兴趣?对于前者,可能有一个简单的算法(尽管我想不出任何算法)。对于后者,您可以使用K-最短路径算法来实现。是的,这很有效。。谢谢请注意,您不需要使用最长路径函数。只要找到从
节点
到边缘的任何路径就足够了。节点
的距离大于1
。