【问题标题】:How do I parallelise this DFS?我如何并行化这个 DFS?
【发布时间】:2021-03-09 17:50:06
【问题描述】:

我有一棵二叉树,其中每个节点的值为0或1,从root到叶子节点的每条路径代表一个一定长度的二进制字符串。该程序的目的是找到所有可能的二进制String(即从root 到叶子的所有可能路径)。现在我想将它并行化,以便它可以使用多个内核。我假设我需要以某种方式拆分分支节点上的工作负载,但我不知道从哪里开始。我正在查看ForkJoin 功能,但我不知道如何拆分工作然后合并它。

public class Tree{
  Node root;
  int levels;

  Tree(int v){
    root = new Node(v);
    levels = 1;
  }
  Tree(){
    root = null;
    levels = 0;
  }
  public static void main(String[] args){
    Tree tree = new Tree(0);
    populate(tree, tree.root, tree.levels);
    tree.printPaths(tree.root);
  }

  public static void populate(Tree t, Node n, int levels){
    levels++;
    if(levels >6){
      n.left = null;
      n.right = null;
    }
    else{
      t.levels = levels;
      n.left = new Node(0);
      n.right = new Node(1);
      populate(t, n.left, levels);
      populate(t, n.right, levels);
    }
  }
  
  void printPaths(Node node)
   {
       int path[] = new int[1000];
       printPathsRecur(node, path, 0);
   }

  void printPathsRecur(Node node, int path[], int pathLen)
    {
        if (node == null)
            return;

        /* append this node to the path array */
        path[pathLen] = node.value;
        pathLen++;

        /* it's a leaf, so print the path that led to here  */
        if (node.left == null && node.right == null)
            printArray(path, pathLen);
        else
        {
            /* otherwise try both subtrees */
            printPathsRecur(node.left, path, pathLen);
            printPathsRecur(node.right, path, pathLen);
        }
    }

    /* Utility function that prints out an array on a line. */
    void printArray(int ints[], int len)
    {
        int i;
        for (i = 0; i < len; i++)
        {
            System.out.print(ints[i] + " ");
        }
        System.out.println("");
    }
}


【问题讨论】:

    标签: java parallel-processing tree binary depth-first-search


    【解决方案1】:

    您可以使用Thread Pools 在单独的线程之间有效地分配负载。

    一种可能的方法:

    ExecutorService service = Executors.newFixedThreadPool(8);
    
    Runnable recursiveRunnable = new Runnable() {
    
        @Override
        public void run() {
            //your recursive code goes here (for every new branch you have a runnable (recommended to have a custom class implementing Runnable))
        }
    };
    service.execute(recursiveRunnable);
    

    但是,这种方法不再是深入的第一次搜索,因为您在搜索第一个之前列出了您职位的子分支。在我的理解中,DFS 是一种严格的线性方法,因此不能完全并行化(尽管请在 cmets 中纠正我)。

    【讨论】:

    • 谢谢,我去看看。我知道,除了“这很困难”之外,我还没有找到关于并行化 DFS 的更多信息。我提供的代码是我将要做的事情的一个极其简化的版本,它需要一个 DFS。
    • 注意:我只是修改了该代码,因此可能存在一些语法错误。注意 2:如果您由于其特定的执行顺序而需要 DFS,那么您不能使其并行,因为您无法保证该顺序将保持任何形式。对于一般用途,它应该足够好。
    猜你喜欢
    • 1970-01-01
    • 2021-11-09
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2016-10-17
    相关资源
    最近更新 更多