当前位置: 首页 > 知识库问答 >
问题:

Java并行化组合

霍弘厚
2023-03-14

我正在尝试并行处理一个组合优化问题。基本上我是想把每个大小为k (n选k)的组合过一遍,看看这个组合是不是最好的。我写了一个可以工作的顺序版本(下面是java代码):

public int bestCombo(int[] al, int[] data, int start, int end, int index, int k) {
    if (index == k) {
        // you have unique combination
        return calculateBestCombination(data);
    } else {
        int best = 0;
        for (int i = start; i <= end && end-i+1 >= k-index; i ++){
            data[index] = al[i];
            int temp = bestCombo(al, data, i+1, end, index+1, k);
            if (best < temp) {
              best = temp
            }
        }
        return best;
    }
}

所以我的代码在递归树的叶子处进行计算,在叶子处,我将有一个唯一的大小k组合,非常简单。现在我将其转换为fork/连接代码,但我没有得到正确的解决方案。这是我在java代码中的fork/连接代码:

public class ParallelizeCombo extends RecursiveTask<MintSolution> {
    private int[] array;
    private int[] data;
    private int start;
    private int end;
    private int index;
    private int k;

    public ParallelizeCombo(int[] arr, int[] data, int start, int end, int index, int k) {
        super();
        this.array = arr;
        this.data = data;
        this.start = start;
        this.end = end;
        this.index = index;
        this.k = k;
    }

    @Override
    protected int compute() {
        // base case, we have reached the end of the combo
        if (this.index == k) {
            return calculateBestCombination(this.data);
        } else {
            List<ParallelizeCombo> subtasks = new ArrayList();
            for (int i = this.start; i <= this.end && this.end-i + 1 >= this.r-this.index; i ++) {
                this.data[this.index] = this.array[i];
                ParallelizeCombo pc = new ParallelizeCombo(this.array, this.data, i+1, this.end, this.index+1, this.k);
                subtasks.add(pc);
            }
            // run subtasks
            for (ParallelizeCombo subtask: subtasks) {
                subtask.fork();
            }
            int best = 0;
            // join the subtasks
            for (ParallelizeCombo subtask: subtasks) {
                int temp = subtask.join();
                if (best < int) {
                    best = int
                }
            }
            return best;
        }
    }
}

我很困惑,因为代码基本相同。唯一的区别是,在fork/join中的for循环中,我在多线程中运行它。然而,我得到的解决方案完全不同,fork/join解决方案非常错误。有人知道为什么吗?

共有1个答案

魏熠彤
2023-03-14

好吧,我想通了。我是个白痴...问题如下:

public ParallelizeCombo(int[] arr, int[] data, int start, int end, int index, int k) {
    super();
    this.array = arr;
    this.data = data;
    this.start = start;
    this.end = end;
    this.index = index;
    this.k = k;
}

在这里,this.data不是创建新数据,而只是指向数据(通过引用)。因此,当您在特定时间对数据计算BestCombination时,它可能不是您认为的组合(其他线程可能已经更改了数据的值)。

 类似资料:
  • 问题内容: 通常,不清楚并行流如何精确地将输入拆分为多个块以及以什么顺序连接这些块。是否有任何方法可以可视化任何流源的整个过程,从而更好地了解发生了什么?假设我创建了这样的流: 我想看一些树状结构: 这意味着将整个输入范围划分为和,然后将范围进一步划分。当然,该图应反映Stream API的实际工作,因此,如果我对此类流执行某些实际操作,则拆分应该以相同的方式执行。 问题答案: 我想用一种解决方案

  • 问题内容: 假设我有一堂课 我试图按班上所有领域分组。如何在JAVA 8中使用并行流来转换 映射的键是类中每个字段的值。JAVA 8以下示例将单个字段分组,如何将一个类的所有字段归为一个Map? 问题答案: 您可以使用的静态工厂方法来实现: 正如Holger在评论中所建议的那样,以下方法可能比上述方法更可取: 它使用的重载方法的行为与我上面建议的语句相同。

  • 问题内容: 您对将尝试获取代码并将其自动拆分为线程的项目有何看法(可能是编译时,可能是在运行时)。 看下面的代码: 这种代码可以自动拆分为两个并行运行的线程。您是否认为有可能?从理论上讲,我感觉这是不可能的(这使我想起了停顿的问题),但是我不能证明这种想法是正确的。 您认为这是一个有用的项目吗?有没有类似的东西? 问题答案: 在一般情况下是否可以知道一段代码是否可以并行化并不重要,因为即使您的算法

  • 我想循环两个列表,将组合传递给函数,并获得以下输出: 由于这是Pyspark,我想将其并行化,因为函数的每个迭代都可以独立运行。 注:我的实际函数是pyspark中的一个长而复杂的算法。只是想贴一个简单的例子来概括。 最好的方法是什么?​

  • 问题内容: 抱歉,如果这是一个幼稚的问题,但我仍在努力解决Snakemake的复杂性。 我有一个目录,其中包含多个文件,这些文件要并行应用规则(即,我想向集群提交相同的脚本,为每个提交指定一个不同的输入文件)。 我首先尝试对输入文件使用expand,但这仅导致提交一份作业: 这里有替代方法吗? 谢谢! 问题答案: 当前,您的工作流确实只包含一次应用“ vep”规则,在此规则中,所有输入和输出都作为

  • 问题内容: 我想并行化以下代码: 由于每一行都可以独立处理,因此我尝试使用它,但是我不知道如何共享DataFrame。我也不确定这是否是与熊猫并行化的最佳方法。有什么帮助吗? 问题答案: 就像@Khris在他的评论中说的那样,您应该将数据帧分成几个大块,并并行地遍历每个块。您可以将数据帧任意分成随机大小的块,但是根据您计划使用的进程数将数据帧分成大小相等的块更有意义。幸运的是,已经有人想出了如何为