Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 整数数组的置换算法_Java_Algorithm_Permutation - Fatal编程技术网

Java 整数数组的置换算法

Java 整数数组的置换算法,java,algorithm,permutation,Java,Algorithm,Permutation,有一个集合,例如(1,4,2,5,7,6,9,8,3)。我们用以下方法计算它的第一个差分(FD):第一个差分[i]=inputArray[i+1]-inputArray[i]。输入阵列是原始设置。在示例中,情况是(1、4、2、5、7、6、9、8、3)。第一个差异是通过以下方式从inputArray创建的:(inputArray的第二个元素)-(inputArray的第一个元素)依此类推 所以给定集合的FD是(3,-2,3,2,-1,3,-1,-5)。任务是找到给定集合的若干置换,其中第一个差分是

有一个集合,例如(1,4,2,5,7,6,9,8,3)。我们用以下方法计算它的
第一个差分
(FD):
第一个差分[i]=inputArray[i+1]-inputArray[i]
。输入阵列是原始设置。在示例中,情况是(1、4、2、5、7、6、9、8、3)。第一个差异是通过以下方式从inputArray创建的:(inputArray的第二个元素)-(inputArray的第一个元素)依此类推

所以给定集合的FD是(3,-2,3,2,-1,3,-1,-5)。任务是找到给定集合的若干置换,其中第一个差分是FD的置换。在这个例子中,我们应该找到(1,4,2,5,7,6,9,8,3)的排列,第一个不同点是(3,-2,3,2,-1,3,-1,-5)的排列

这是我的算法:

  • 求给定集合的所有置换
  • 求给定集合的FD
  • 找出我们集合中排列的所有第一个差异
  • 仅选择这样的集合,其中第一个差分包含给定集合的FD数。数一数

  • 但是这个算法太慢了。你能帮助创建更快的算法吗?也许我做了一些可以消除的步骤

    这是个大问题。。。如果我理解的没错,你需要找到原始集合的所有置换,它们保持了原始FD集合的置换

    你的算法可以工作,除了你通过查看原始集合的所有排列,然后是那些FD的所有排列,来计算许多不必要的排列。如果您首先查看原始FD的所有可能排列,您应该能够消除原始集合的一组排列

    换句话说:

  • 计算您的原始FD
  • 找到原始FD的所有可能排列
  • 然后,线性地开始计算原始集合的置换,但消除那些立即无法计算的置换
  • 例如:

    集合{1,2,3,5} FD{1,1,2}


    在计算该示例时,当您进入步骤3时,您应该能够自动消除以1、5开头的任何排列,因为4的差永远不会出现在原始FD的任何排列中。在这个特定的例子中,它只会为您节省一些计算,但是一旦您开始使用更大的集合,这个算法就有可能为您节省大量的时间。

    您不需要计算置换。首先要注意的是,在您的示例中,差分数组中有17个从-8到8的可能值,但实际数组中只有五个不同的值

    制作一个矩阵并划掉所有未出现的值(括号中):

    如果原始数组中的当前项为1,则下一项必须为4或3,否则将无法获得差分数组的排列。您可以将此信息存储在图形中:

    1 -> 4, 3
    2 -> 1, 4, 5
    3 -> 1, 2, 5, 6
    4 -> 2, 7, 6, 3
    5 -> 4, 7, 8, 3
    6 -> 1, 4, 5, 9, 8
    7 -> 2, 5, 6, 9
    8 -> 7, 6, 3
    9 -> 4, 7, 8
    
    现在,将目标差异数组转换为一个映射,在该映射中存储元素在数组中出现的频率:

    count[-5]: 1
    count[-2]: 1
    count[-1]: 2
    count[2]: 1
    count[3]: 3
    
    然后可以在图形中查找原始数组长度的路径。您必须跟踪是否已访问某个节点。您还应该通过递减“count”来跟踪已经使用的差异。如果找到了所需长度的路径,则具有有效的排列

    在伪代码中:

    map count;
    set visited;
    
    function walk(a, left, path) {
        left--;
    
        if (left == 0) {
            print path;
            return;
        }
    
        a.visited = true;
    
        foreach (b in graph[a]) {
            d = b - a;
    
            if (count[d] > 0 && b.visited == false) {
                count[d]--;
                walk(b, left, path + [b]);
                count[d]++;
        }
    
        a.visited = false;
    }
    
    
    foreach (a in A) {
        walk(a, A.length, [a]);
    }
    

    任务是找到给定集合的若干排列,其中第一个不同点是FD的排列。
    您能详细说明一下吗?此外,如果你格式化你的问题,它会更可读。与您现在的文本块相比,请详细说明FD的排列。您所说的FD的排列是什么意思?我不明白的一件事是如何找到可以消除的集合。我应该如何处理原始集合以找到永远不会出现在FD中的数字?您打算如何找到给定集合的所有置换?基本上,您只需采用相同的逻辑,并在排列中的下一个数字产生FD中没有的差异时添加停止功能。这种a-la DFS方法肯定比原始暴力尝试和公认答案(阶乘(!)复杂性)更快。我不确定给定解决方案的确切复杂度是多少,但感觉仍然可以优化,例如任何解决方案集中最后一个和第一个元素之间的距离(或
    路径
    始终与原始设置中的
    最后一个
    -
    第一个
    相同。无论如何,+1我同意最后一张海报…这绝对是一个比我原始答案更好的解决方案。我喜欢从条目之间的差异来解决问题,而不是从单个排列来解决问题。这将定义它ely的构建开销要大得多,但与我的算法相比,它的运行速度会非常快。干得好!+1
    map count;
    set visited;
    
    function walk(a, left, path) {
        left--;
    
        if (left == 0) {
            print path;
            return;
        }
    
        a.visited = true;
    
        foreach (b in graph[a]) {
            d = b - a;
    
            if (count[d] > 0 && b.visited == false) {
                count[d]--;
                walk(b, left, path + [b]);
                count[d]++;
        }
    
        a.visited = false;
    }
    
    
    foreach (a in A) {
        walk(a, A.length, [a]);
    }