计算subgrah的重量

时间:2013-04-18 19:13:18

标签: java algorithm graph-algorithm jung

我需要请求你的帮助,因为我多年来一直在努力解决我的问题而且找不到合适的解决方案。我想找到包含节点的subgrah的权重(将成为我的方法的参数)并将以中心节点0结束。我知道它听起来很愚蠢,但图像在这里将是一个很好的帮助(http://img542.imageshack.us/img542/5400/zrzutekranu20130418o205.png)。  例如,getWeight(8)将返回21,如果我们运行getWeight(7)(9,10)则相同。 getWeight(2)= 7.我写了这样的方法,但有时我得到Stack Overflow Exception :(

    private void getWeight(Object node, Object source) {
        Collection nodeCollection = graph.getNeighbors(node);
        for (Object n : nodeCollection) {
            if ((Integer) n == 0) {
                weight += ((MyEdge) (graph.findEdge(startNode, node))).getW();
            } else {
                if (n != source) {          
                    weight += ((MyEdge) (graph.findEdge(node, n))).getW();
                    getWeight(n, node);
                } else {
                }

            }
        }
       return weight;
    }

我正在使用jung2 lib。

请帮忙,你是我最后的希望!

@ Zim-Zam O'Pootertoot:喜欢这个?

ArrayList<Boolean> visited = new ArrayList<Boolean>();
public void getWeight2(Object i) {
    visited.set((Integer) i, true);
    for (Object v : getGraph().getNeighbors(i)) {
        if (!visited.get((Integer) v)) {
            if (getGraph().getNeighborCount(v) > 1 & !v.equals(startNode)) {
                weight += ((MyEdge) getGraph().findEdge(i, v)).getW();
                getWeight2(v);
            } else {
                weight += ((MyEdge) getGraph().findEdge(i, v)).getW();

            }
        }
    }
}

仍然是SOExp;(

2 个答案:

答案 0 :(得分:2)

看起来你是在重复计算节点。您可以创建一个HashSet,并将其传递给包含您已访问过的节点的getWeight; for循环将跳过集合中的节点,并将nodeCollection与hashset结合。

另一种选择是在您的节点中放置一个访问标志 - 将它们初始化为false,并在您访问节点时将它们设置为true。棘手的部分是在你做的时候将所有的标志重置为假 - 为此我建议你保留一个单独的所有节点列表,这样你就可以迭代它来重置标志,而不必再次遍历你的图形

答案 1 :(得分:1)

我对 jung 一无所知,但是这个伪java概述了一种方法来进行你正在寻找的重量计数,它保留了一个地图来跟踪被访问的节点和被访问的边缘(为了避免重新计算任何一个),你必须用api等效方法填补空白并进行调整:

private int calculateWeight(Object startNode, HashMap<Node, Boolean> visitedNodes, HashMap<Edge, Boolean> visitedEdges) {
    int w = 0;
    if (!visitedNodes.get(startNode)) {
        // Don't know if this method (getEdeges) exists, but if you could implement 
        // a way to get all the edges that go out from a node, then paste the code  here 
        //
        // Get the edges from the node
        Collection edges = startNode.getEdges();

        for (Object edge : edges) { 
            // If the edge haven't been visited, then add its weight to w
            if (!visitedEdges.get(edge)) {
                w += edge.getW();
                // Mark the edge as visited 
                visitedEdges.put(edge, true);
            }
        }
        // We are done with this node, mark it as visited
        visitedNodes.put(startNode, true);

        // Check the neighbors of this node recursively 
        Collection neighborNodes = getGraph().getNeighbors(startNode);
        for (Object node : neighborNodes) {
            // Go recursively with this node, passing in the visited nodes and edges maps to avoid recounting
            w += calculateWeight(node, visitedNodes, visitedEdges);                
        }
    }
    return w;
}

// Then, use the above method like this 
public static void main(String... args) { 
    HashMap<Node, Boolean> visitedNodes = new HashMap<Node, Boolean>();
    HashMap<Edge, Boolean> visitedEdges = new HashMap<Edge, Boolean>();

    // Search the startNode and nodeZero from the graph...

    // Add the Node 0 to the visitedNodes map, so the zero node won't be processed 
    visitedNodes.put(nodeZero, true);

    int w = calculateWeight(startNode, visitedNodes, visitedEdges);
}

警告:这只是一个伪java,我还没有测试过它

希望这有助于或至少为您提供解决问题的提示