Question

I need to ask for your help, as I've been struggling with my problem for many days and didn't find any suitable solution. I want to find weight of subgrah that contains node (going to be a parameter of my method) and will end with central node 0. I know it sounds stupid but image will be a great help here (http://img542.imageshack.us/img542/5400/zrzutekranu20130418o205.png). For example getWeight(8) will return 21, the same if we run getWeight(7) (9,10). getWeight(2) = 7. I wrote such method however sometimes I'm getting 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;
    }

I'm using jung2 lib.

Please help, you are my last hope!

@Zim-Zam O'Pootertoot: Like this?

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();

            }
        }
    }
}

Still SOExp ;(

Was it helpful?

Solution 2

I don't know anything about jung, but this pseudo java outlines a way to do the weight counting you're looking for, it keeps a maps to track down the visited nodes and the visited edges (to avoid recounting any of then), you have to fill in the gaps with api equivalent methods and make the adjustments:

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);
}

Warning: This is just a pseudo java, I haven't test it

Hope this helps or at least give you a hint to solve the problem

OTHER TIPS

It looks like you're double-counting nodes. You could create a HashSet that you pass in to getWeight that contains the nodes you've already visited; the for loop will skip nodes that are in the set, and will union nodeCollection with the hashset.

Another option is to put a visited flag in your nodes - initialize them to false, and set them to true when you've visited the node. The tricky part is resetting all of the flags to false when you're doe - for this I recommend that you keep a separate list of all of your nodes so that you can iterate through it to reset the flags without having to traverse your graph again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top