Parallel processing 用于蛮力箱包装并行化的第N个置换算法(多次包含同一项)

Parallel processing 用于蛮力箱包装并行化的第N个置换算法(多次包含同一项),parallel-processing,permutation,bin-packing,Parallel Processing,Permutation,Bin Packing,我已经编写了一个带有蛮力包装器的小程序,用于实时计算网上商店订单的运输成本。许多订单包含少量物品,这使得暴力是对其他算法的合理补充 由于订单可以多次包含相同的项目(即重复/重复/相同的元素),因此我采用了词汇排列算法 现在我尝试添加一些并行化/多线程,并发现了一些问题。但是,没有人考虑到订单可以多次包含相同的项目 理想情况下,我可以将排列的数量除以线程的数量,让每个线程计算其起点并运行特定数量的迭代 这样的算法存在吗 -- 更新: 对。根据链接答案改编的Java代码: public static

我已经编写了一个带有蛮力包装器的小程序,用于实时计算网上商店订单的运输成本。许多订单包含少量物品,这使得暴力是对其他算法的合理补充

由于订单可以多次包含相同的项目(即重复/重复/相同的元素),因此我采用了词汇排列算法

现在我尝试添加一些并行化/多线程,并发现了一些问题。但是,没有人考虑到订单可以多次包含相同的项目

理想情况下,我可以将排列的数量除以线程的数量,让每个线程计算其起点并运行特定数量的迭代

这样的算法存在吗

--

更新:

对。根据链接答案改编的Java代码:

public static int[] unrank(int[] frequencies, int rank) {
    // https://stackoverflow.com/questions/22642151/finding-the-ranking-of-a-word-permutations-with-duplicate-letters

    int count = 0;
    for(int f : frequencies) {
        count += f;
    }

    int permutationCount = 1;
    int first = firstDuplicate(frequencies);
    if(first == -1) {
        for(int i = 0; i < count; i++) {
            permutationCount = permutationCount * (i + 1);
        }

        // use classic n-th lexographical permutation algorithm
        throw new RuntimeException("Not implemented");
    } else {
        for(int i = frequencies[first]; i < count; i++) {
            permutationCount = permutationCount * (i + 1);
        }
        for(int i = first + 1; i < frequencies.length; i++) {
            if(frequencies[i] > 1) {
                for(int k = 1; k < frequencies[i]; k++) {
                    permutationCount = permutationCount / (k + 1);
                }
            }
        }

        return unrank(frequencies, count, permutationCount, rank);
    }

}

private static int firstDuplicate(int[] frequencies) {
    for(int i = 0; i < frequencies.length; i++) {
        if(frequencies[i] > 1) {
            return i;
        }
    }
    return -1;
}   

private static int[] unrank(int[] frequencies, int elementCount, int permutationCount, int rank) {
    int[] result = new int[elementCount];

    for(int i = 0; i < elementCount; i++) {
        for(int k = 0; k < frequencies.length; k++) {
            if(frequencies[k] == 0) {
                continue;
            }
            int suffixcount = permutationCount * frequencies[k] / (elementCount - i);
            if (rank <= suffixcount) {
                result[i] = k;

                permutationCount = suffixcount;

                frequencies[k]--;
                break;
            }
            rank -= suffixcount;
        }
    }
    return result;
}
public static int[]unrank(int[]frequencies,int-rank){
// https://stackoverflow.com/questions/22642151/finding-the-ranking-of-a-word-permutations-with-duplicate-letters
整数计数=0;
用于(int f:频率){
计数+=f;
}
int置换计数=1;
int first=firstDuplicate(频率);
如果(第一个==-1){
for(int i=0;i1){
对于(int k=1;k1){
返回i;
}
}
返回-1;
}   
私有静态int[]取消存储(int[]频率、int元素计数、int置换计数、int秩){
int[]结果=新的int[elementCount];
for(int i=0;i
这是代码,我正在从手机上粘贴它,因此我无法执行代码块,但您可以在我的github@oriyonay上的Project Euler Solutions/Euler24.java:)下找到它

公共静态字符串置换(字符串s、数组列表数字、int p){
如果(p==1){
对于(整数i:数字)s+=i;
返回s;
}
int fact=factorial(digits.size()-1);
INTN=(p%fact==0)?(p/fact)-1:p/fact;
s+=数字。获取(n);
数字。删除(n);
返回置换(s,数字,p-(n*fact));
}

我希望这是有帮助的!

您正在搜索的是一个针对重复排列的排序算法,到目前为止,我知道在线程()的答案中没有一个你会发现一个没有多线程的。我已经读了一些where,但不知道在哪里。你可以通过使用一些树来提高复杂性。

这会在同一项occor多次出现时产生重复项。或者更确切地说,unranking;能够使pyhton代码完美地适应我的要求。
@Test
public void testUnranking() {
    int count = (7 * 6 * 5 * 4 * 3 * 2 * 1) / ((4 * 3 * 2 * 1) * (3 * 2 * 1));
    for(int i = 0; i < count; i++) {
        int[] frequencies = new int[2];
        frequencies[0] = 3;
        frequencies[1] = 4;

        System.out.println(Arrays.asList(NthPermutationRotationIterator.unrank(frequencies, i + 1)));
    }
}
public static String permutation(String s, ArrayList<Integer> digits, int p) {
    if (p == 1) {
      for (int i: digits) s+= i;
      return s;
    }
    int fact = factorial(digits.size() - 1);
    int n = (p % fact == 0) ? (p / fact) - 1 : p / fact;
    s+= digits.get(n);
    digits.remove(n);
    return permutation(s, digits, p - (n*fact));
  }