引起无限循环的关节点算法

时间:2016-04-07 13:34:12

标签: java algorithm graph

我正在尝试识别图形中的节点,如果使用迭代关节点算法删除节点,将导致所述图形断开连接,如下所示:

public class ArticulationPointsFinder {
    Node start; 
    ArrayList<Node> articulationPoints = new ArrayList<Node>();

    public ArticulationPointsFinder(Node start) {

        // Set the start point and mark the depth as 0
        this.start = start;
        start.articulationDepth(0);

        int numberOfRootSubtrees = 0;

        // foreach neighbour of the start
        for (Node neighbour : start.neighbouringNodes()) {
            if (neighbour.articulationDepth() == null) {
                this.iterativeArticulation(neighbour, start);
                numberOfRootSubtrees++;
            }
        }

        // Add the root node the articulation points
        if (numberOfRootSubtrees > 1) {
            this.articulationPoints.add(start);
        }

        // Cleanup depth on nodes
    }

    private void iterativeArticulation(Node currentNode, Node root) {
        Stack<ArticulationPointNode> nodeStack = new Stack<ArticulationPointNode>();

        nodeStack.push(new ArticulationPointNode(currentNode, 1, new ArticulationPointNode(root, 0, null, 0, null), 0, null));

        while (!nodeStack.isEmpty()) {
            ArticulationPointNode elem = nodeStack.peek();
            Node node = elem.node();

            // Initialize
            if (elem.parent().children() == null) {
                node.articulationDepth(elem.reach());
                elem.reach(elem.parent().depth());
                elem.parent().children(new LinkedList<Node>());

                // Check neighbours
                for(Node neighbour : node.neighbouringNodes()) {
                    if (!elem.parent().node().equals(neighbour)) {
                        elem.parent().children().add(neighbour);
                    }
                }
            // Nodes to process 
            } else if (!elem.parent().children().isEmpty()) {               

                while (!elem.parent().children().isEmpty()) {
                    Node child = elem.parent().children().poll();

                    if (child.articulationDepth() != null) {
                        elem.reach(Math.min(elem.reach(), child.articulationDepth()));
                    } else {
                        nodeStack.push(new ArticulationPointNode(child, node.articulationDepth() + 1, elem, 0, null));
                    }
                }   

            // Lastly   
            } else {
                if (!node.equals(currentNode)) {
                    if (elem.reach() >= elem.parent().depth()) {
                        this.articulationPoints.add(elem.parent().node());
                    }
                    elem.parent().reach(Math.min(elem.parent().reach(), elem.reach()));
                    nodeStack.pop();
                }
            }
        }
    }
}

这是我的POJO存储在堆栈中:

public class ArticulationPointNode {
    private Node currentNode;
    private int reach, depth;
    private ArticulationPointNode parent;
    private Queue<Node> children;

    public ArticulationPointNode(Node currentNode, int reach, ArticulationPointNode parent, int depth, Queue<Node> children) {
        this.currentNode = currentNode;
        this.reach = reach;
        this.parent = parent;
        this.depth = depth;
        this.children = children;
    }

    public Node node() {
        return this.currentNode;
    }

    public int reach() {
        return this.reach;
    }

    public void reach(int reach) {
        this.reach = reach;
    }

    public ArticulationPointNode parent() {
        return this.parent;
    }   

    public int depth() {
        return this.depth;
    }

    public Queue<Node> children() {
        return this.children;
    }

    public void children(Queue<Node> queue) {
        this.children = queue;
    }
}

目前,当在小型数据集上运行时,这会导致无限循环,并且单步执行,我无法轻易确定其无限迭代的原因。想法?

0 个答案:

没有答案