我问了一个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
之后。因此,我想消除A2
和B2
对(即A
和B
永远不应该直接跳转到2
...他们应该永远去首先通过1
。此外,1
永远不应跳转到2
以外的任何数字,因为2
总是紧跟在0
之后。此外,请注意B
和3
之间始终如何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}}
换句话说,我试图从这个有向无环图中找到:
对此:
我应该使用什么样的算法/逻辑来摆脱这些无关的对(即图形边缘)?或者你认为我首先生成对的逻辑是应该改变的东西吗?
答案 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)
简单易行。如果图表不是太大,它可能也足够有效。
n
拉出,让d
成为其开头的距离。查看所有直接子项,如果有任何标记为1,则从开始删除边缘,将n
的所有子项放入标有距离d+1
的队列中。从队列中拉出下一个节点。JSPerfUnkn0wn所说的内容,只是更详细一点。
答案 2 :(得分:0)
由于图表是非循环的,因此可能的解决方案是应用您最喜欢的最短路径算法(Bellman-frod,Floyd-Warshal等),但翻译比较条件(以便更长的路径赢得更短的路径)。