谁可以帮助一个可能的动态编程算法

时间:2011-03-31 23:55:32

标签: algorithm


首先让我为我即将陈述我的问题的粗暴方式道歉。我在这里指的是另一个站点的成员告诉我,我正在寻找动态编程算法....我的问题如下。

我正在尝试对一些数据进行排序,并且需要在数字中找到可能的序列 两组数据都包含不同顺序中列出的相同数字,如下例所示。

54 47 33 58 46 38 48 37 56 52 61 25 ..................第一套
54 52 33 61 38 58 37 25 48 56 47 46 ..................第二套

在此示例中,从左到右阅读数字54 52 61和25以相同的顺序出现在两个集合中 所以其他可能的解决方案是......

54 52 61 25
54 33 58 46
54 33 46
54 33 38 48 56
54 48 56 ....等等。

虽然这可以手工完成,但我有很多这样的事情可以通过,我一直在犯错误。 有谁知道现有的程序或脚本会输出所有可能的解决方案吗?

我理解c ++和虚拟基础程序的基本结构,并且应该能够在以太网中拼凑一些东西,但说实话,自zx频谱时代以来我没有做过任何严肃的编程,所以请放轻松我。然而,我的主要问题不在于程序语言本身,而是由于某种原因,我发现无法编写为了用英语完成这项任务所需的步骤,更不用说任何其他语言了。

达西

2 个答案:

答案 0 :(得分:4)

听起来你正在寻找'所有常见的子序列(ACS)',它是(更常见的)longest common subsequence problem (LCS)的表亲。

这是一个paper discussing ACS(虽然他们专注于计算子序列,而不是枚举)。

要想出算法,您应该更精确地定义所需的输出。为了论证,假设您希望子序列集不再包含在任何更长的子序列中。然后一个算法是:

1)对LCS应用DP算法,生成对齐/回溯矩阵

2)回溯所有可能的LCS,标记所访问的对齐位置。

3)选择尚未标记的矩阵的最大元素(剩余的最长子序列)

4)回溯,记录序列并标记所访问的对齐位置。

5)虽然存在未标记的对齐位置,但是转到(3)

回溯你的情况很复杂,因为你必须访问所有可能的路径(称为“所有最长的公共子序列”)。您可以找到LCS here的示例实现,这可能有助于您入门。

答案 1 :(得分:1)

我写了这段代码,它输出了最长的公共序列。然而,它不是超级优化的,顺序是O(n * m)n - > array1 size,m-> array2大小:

private void start() {
    int []a = {54, 47, 33, 58, 46, 38, 48, 37, 56, 52, 61, 25};
    int []b = {54, 52, 33, 61, 38, 58, 37, 25, 48, 56, 47, 46};

    System.out.println(search(a,b));
}

private String search(int[] a, int[] b)
{
    return search(a, b, 0, 0).toString();       
}

private Vector<Integer> search(int[] a, int[] b, int s1, int s2) {

    Vector<Vector<Integer>> v = new Vector<Vector<Integer>>(); 

    for ( int i = s1; i < a.length; i++ )
    {
        int newS2 = find(b, a[i], s2);
        if ( newS2 != -1 )
        {
            Vector<Integer> temp = new Vector<Integer>();
            temp.add(a[i]);
            Vector<Integer> others = search(a, b, i+1, newS2 + 1); 
            for ( int k = 0; k < others.size(); k++)
                temp.add( others.get(k));
            v.add(temp);
        }
    }

    int maxSize = 0;
    Vector<Integer> ret = new Vector<Integer>();
    for ( int i = 0; i < v.size(); i++)
        if ( v.get(i).size() > maxSize )
        {
            maxSize = v.get(i).size(); 
            ret = v.get(i);
        }

    return ret;
}

private int find(int[] b, int elemToFind, int s2) {
    for ( int j = s2; j < b.length; j++)
        if ( b[j] == elemToFind)
            return j;
    return -1;
}