在尝试寻找最长路径时消除有向无环图中的无关边缘

时间:2012-01-01 04:24:57

标签: javascript algorithm graph directed-acyclic-graphs

我问了一个question关于在可变数量的集合中找到没有重复字符的子序列。解决方案是创建每对字母的矩阵,丢弃每组中没有出现的字母,然后在有向非循环图中找到longest path。但是,我不想只是最长的路径,我想要几个最长的路径(例如,如果它生成长度为10,10,9,8,8,3,3,2和1的子序列,我可能想要仅显示前5个子序列。

因此,由于我不是只寻找最长路径,为了生成结果子序列,而不是使用维基百科文章中描述的最长路径算法,我使用的是一个简单生成的简单算法所有可能子序列的列表。这会生成一个类似于前一个问题的an answer结果的集合。

问题在于我想减少它产生的子序列的数量。

例如,如果我有以下几组:

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之后。因此,我想消除A2B2对(即AB永远不应该直接跳转到2 ...他们应该永远去首先通过1。此外,1永远不应跳转到2以外的任何数字,因为2总是紧跟在0之后。此外,请注意B3之间始终如何B3,因此我希望消除B对(同样,0应始终通过3 {1}}在跳转到B < 0 < 3之前,因为所有集合都将这三个字母的位置设为:A)。

为了清楚起见,当前的算法将提出这些子序列:(为了简洁起见,我只包括那些以A1234 A124 * A134 * A14 * A234 * A24 * A34 * A4 * A034 A04 * 开头的算法):

*

...所有标有A - 1 B - 1 1 - 2 2 - 3 0 - 3 3 - 4 0 0 的人都应该被淘汰。

产生所需子序列的(正确)对将是:

A1234
A034
B1234
B034
1234
234
034
34

...并且子序列的完整列表将是:

{{1}}

换句话说,我试图从这个有向无环图中找到:

enter image description here

对此:

enter image description here

我应该使用什么样的算法/逻辑来摆脱这些无关的对(即图形边缘)?或者你认为我首先生成对的逻辑是应该改变的东西吗?

3 个答案:

答案 0 :(得分:2)

  

此外,请注意B和3之间总是出现0,所以我想消除B3对(同样,在跳转到3之前,B应该总是经过0,因为所有集合都有这三个字母的位置为:B <0 <3)。

嗯,好的,如果n0 < n1 < n2在所有集上都有,那么删除所有(n0, n2)对?这可以用this(在pseudoPython中)实现:

for(edge in node):
    if(len(LongestPath(node, edge.Node)) > 1):
        RemovePair(node, edge.Node)

答案 1 :(得分:1)

简单易行。如果图表不是太大,它可能也足够有效。

  • 对于每个节点(从没有传入边的节点开始),遵循所有路径,标记距离,用1标记所有直接子节点并将它们放入队列中。当队列不为空时,将节点n拉出,让d成为其开头的距离。查看所有直接子项,如果有任何标记为1,则从开始删除边缘,将n的所有子项放入标有距离d+1的队列中。从队列中拉出下一个节点。

JSPerfUnkn0wn所说的内容,只是更详细一点。

答案 2 :(得分:0)

由于图表是非循环的,因此可能的解决方案是应用您最喜欢的最短路径算法(Bellman-frod,Floyd-Warshal等),但翻译比较条件(以便更长的路径赢得更短的路径)。