Search code examples
javagraphbellman-ford

How to test if a weighted graph has a negative cycle


I need to create a test that returns true if the graph (directed graph) as a parameter has a cycle of negative weight, false otherwise.

For now I created this. Theoretically should check if there are "generic" cycles, not if there are negative cycles. How can I change the method? There's an easier or efficient?

//if there is a negative cycle, get out and return 
public void bellmanFord(Graph<V, E> graph, V source, V dest) {
    ArrayList<V> vertices = (ArrayList<V>) graph.getVertices();
    HashMap<V, Boolean> visited = new HashMap<V, Boolean>(vertices.size());
    for(V v : vertices) { 
        visited.put(v, false);
    }
    boolean cycle = hasNegativeCycle(graph, source, visited, vertices);
    if(cycle == true)
        return;
    else {
        ...
    }

}

public boolean hasNegativeCycle(Graph<V, E> graph, V source, HashMap<V, Boolean> visited, ArrayList<V> vertices) {
    visited.put(source, true);
    for(V u : vertices) {
      ArrayList<V> neigh_u = (ArrayList<V>) graph.getNeighbors(u);
      for(V v : neigh_u) {
        if(visited.get(v) == true || hasNegativeCycle(graph, v, visited, vertices)) {
          return true;
        }
      }
    }
    return false;
}

Thanks


EDIT: As you can see from the method name written on it, I'm trying to implement the algorithm of Bellman-Ford and I'm following this pseudocode:

BellmanFord(Graph G, Vertex start) { 
    foreach(Vertex u of G) { 
        dist[u] = ∞; 
        prev[u] = -1; 
    } 
    prev[start] = s; 
    dist[start] = 0; 
    repeat n times { 
        foreach(Vertex u of G) { 
            foreach(Vertex v near u) { 
                if(dist[u] + weigth_uv < dist[v]) { 
                    prev[v] = u; 
                    dist[v] = dist[u] + weigth_uv; 
                } 
            } 
        } 
    } 
}

Solution

  • You have to apply Bellman-Ford Algorithm.Wikipedia has proper pseudocode. If you apply this properly your problem will be solved.

    function BellmanFord(list vertices, list edges, vertex source)
       ::distance[],predecessor[]
    
       // This implementation takes in a graph, represented as
       // lists of vertices and edges, and fills two arrays
       // (distance and predecessor) with shortest-path
       // (less cost/distance/metric) information
    
       // Step 1: initialize graph
       for each vertex v in vertices:
           if v is source then distance[v] := 0
           else distance[v] := inf
           predecessor[v] := null
    
       // Step 2: relax edges repeatedly
       for i from 1 to size(vertices)-1:
           for each edge (u, v) in Graph with weight w in edges:
               if distance[u] + w < distance[v]:
                   distance[v] := distance[u] + w
                   predecessor[v] := u
    
       // Step 3: check for negative-weight cycles
       for each edge (u, v) in Graph with weight w in edges:
           if distance[u] + w < distance[v]:
               error "Graph contains a negative-weight cycle"
       return distance[], predecessor[]