使用fork-join进行Java多路树搜索

时间:2013-01-09 18:45:18

标签: java algorithm java-7

我有多路树结构,我必须遍历以确定状态。我正在研究'Post-Order'类型遍历,其中首先处理叶节点。并且搜索结束条件取决于具有状态不活动的任何子节点。另外,从性能角度来看,我将使用JDK7的fork-join机制。

enter image description here

1 个答案:

答案 0 :(得分:1)

这是一个(非常)粗略的草图,说明如何做到这一点。

final class TreeNode {
    private final Iterable<TreeNode> children;

    TreeNode(Iterable<TreeNode> aChildren) {
        children = aChildren;
    }

    Iterable<TreeNode> getChildren() {
        return children;
    }

    void postorder(TreeNodeIterator iterator) {
        postorderTraverse(this, iterator);
    }

    private void postorderTraverse(TreeNode node, TreeNodeIterator iterator) {
        for (TreeNode child : children) {
            postorderTraverse(child, iterator);
        }
        iterator.visit(node);
    }

    void postorderParallel(TreeNodeIterator iterator) {
        new ForkJoinPool().invoke(new VisitNodeAction(iterator, this));
    }

    interface TreeNodeIterator {
        void visit(TreeNode child);
    }

    private class VisitNodeAction extends RecursiveAction {
        private final TreeNodeIterator iterator;
        private final TreeNode node;

        private VisitNodeAction(TreeNodeIterator iterator, TreeNode node) {
            this.iterator = iterator;
            this.node = node;
        }

        @Override
        protected void compute() {
            List<RecursiveAction> tasks = new LinkedList<RecursiveAction>();
            for (TreeNode child : children) {
                tasks.add(new VisitNodeAction(iterator, child));
            }
            invokeAll(tasks);
            iterator.visit(node);
        }
    }
}

有些事情需要修改:

  • 添加对状态为非活动状态的检查。最简单的方法是在处理节点之前检查的每个RecursiveAction中保留一个原子布尔值,并在节点处于非活动状态时更新,尽管这不是一个非常干净或功能性的路径。
  • 添加一种方法来决定何时应该使用新线程,上面为每个节点使用一个线程。此外,您可以通过在每次ForkJoinPool调用时不创建postorderParallel来优化它。