How to test if a weighted graph has a negative cycle - java

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

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[]

You may want to do a BFS traversal of the graph. At each node visit, record the node's unique id (.hashCode() for example, if implemented) into a HashSet. Whenever you are trying to insert an already present element into the hashset, you found a circle.
If you found a circle in say node F, you can count the circle's sum weight by traversing the tree upwards, until you find F again, and summing the weights.
Of course after determining the circle size, and it was positive, you must continue the BFS traversal, but without traversing F's children. If it was negative, return from the function, as you found a negative circle.
Edit: you can also keep track of the current sum weight during the BFS traversal steps, this way you don't have to traverse the tree upwards to calculate the total weight...As your graph is Directed, this method would fit also better...

Related

How to implement Depth First Search on a directed graph to visit all vertices

How do we perform depth first search on a directed graph using an adjacency matrix in which it explores all of the vertices starting from a random vertex? I attempted to implement dfs, but its only exploring the vertices that are reachable from the starting vertex.
public static void dfs(int [] [] adjMatrix, int startingV,int n)
{
boolean [] visited = new boolean[n];
Stack<Integer> s = new Stack<Integer>();
s.push(startingV);
while(!s.isEmpty())
{
int vertex = s.pop();
if(visited[vertex]==false)
{
System.out.print("\n"+(v));
visited[vertex]=true;
}
for ( int i = 0; i < n; i++)
{
if((adjMatrix[vertex][i] == true) && (visited[i] == false))
{
s.push(vertex);
visited[I]=true;
System.out.print(" " + i);
vertex = i;
}
}
}
}
}
In a directed graph there might be no node from which you can reach all other nodes. So what do you expect in this case?
If there is at least one node from which you can reach all other nodes you only do now know which one it is, you can select a random one, go against the direction of an incoming edge to find a root node from which you can reach all other nodes.
Your code has a couple of issues, one of which is that you do a int vertex = s.pop(); and later an s.push(vertex); with the same vertex. The latter should probably be s.push(i); instead.
The easiest way to implement DF traversal is to just use recursion. Then the code decays to
function dfs(v) {
if v not visited before {
mark v as visited;
for every adjacent vertex a of v do {
dfs(a);
}
do something with v; // this is *after* all descendants have been visited.
}
}
Of course, every recursive implementation can be equivalently implemented using a stack and iteration instead, but in your case that'd be somewhat more complicated because you'd not only have to store the current vertex on the stack but also the state of iteration over its descendants (loop variable i in your case).

Dijkstra's Algorithm Java implementation with Priority Queue

Hi I am trying to find an minimum possible route in my weighted graph using Dijkstra'a algorithm. I am trying to implement the algorithm below from geeksforgeeks.com :
1) Initialize distances of all vertices as infinite.
2) Create an empty priority_queue pq. Every item
of pq is a pair (weight, vertex). Weight (or
distance) is used used as first item of pair
as first item is by default used to compare
two pairs
3) Insert source vertex into pq and make its
distance as 0.
4) While either pq doesn't become empty
a) Extract minimum distance vertex from pq.
Let the extracted vertex be u.
b) Loop through all adjacent of u and do
following for every vertex v.
// If there is a shorter path to v
// through u.
If dist[v] > dist[u] + weight(u, v)
(i) Update distance of v, i.e., do
dist[v] = dist[u] + weight(u, v)
(ii) Insert v into the pq (Even if v is
already there)
5) Print distance array dist[] to print all shortest
paths.
My main Data Structures are:
// HashMap of Intersections
private static HashMap<String, Intersection> intersections;
// Edge/Rail List
private static ArrayList<Rail> railList;
My function below called route and it first gets source and destination
vertexes from the commands as String and then i try to implement algorithm above. However i do not know how to store them in final Arraylist so that i can return the path.Additionally, it is problematic i think:
public void route(String wholeLine){
String[] temp = wholeLine.split(" |\\>");
int vel = Integer.parseInt(temp[3]);
double totalpath = 0;
int numOfSwitches = 0;
// My Source and Destination Nodes
Intersection src = intersections.get(temp[1]);
Intersection dest = intersections.get(temp[2]);
// Start the operation
PriorityQueue<Intersection> pq = new PriorityQueue<RailNetwork.Intersection>();
// Setting Distance to 0 for Source Node
src.setDistanceFromSource(0);
pq.add(src);
// While Priority Queue not empty
while(pq.size() != 0){
// Extract the vertex with minimum distance value node from Min Heap. Let the extracted vertex be u.
Intersection u = pq.remove();
// For every adjacent vertex v of u, check if v is in Min Heap.
for(Intersection v : u.getNeigbours()){
double weight = 0;
// Find edgeweight of u and v from rail/edge list
for(int i = 0;i<railList.size();i++){
if(railList.get(i).getSrc().getLabel().equals(u.label) && railList.get(i).getDest().getLabel().equals(v.label)){
weight = railList.get(i).getDistance();
}
else if(railList.get(i).getSrc().getLabel().equals(v.label) && railList.get(i).getDest().getLabel().equals(u.label)){
weight = railList.get(i).getDistance();
}
}
//If v is in Min Heap and distance value is more than weight of u-v plus distance value of u, then update the distance value of v.
if(u.getDistanceFromSource() > v.getDistanceFromSource() + weight){
//Update distance of v, i.e., do dist[v] = dist[u] + weight(u, v)
v.setDistanceFromSource(u.getDistanceFromSource() + weight);
System.out.println(v.label + "\t" + v.distanceFromSource);
pq.add(v);
}
}
}
}
**Could someone please help me to find my mistakes in order to implement it correctly?**Any help or hint is appreciated. Thanks in advance stackoverflow family.

BFS Find Shortest Path of 2d matrix using 2 queues

What I'm trying to do:
Using a graph found in a text file, find and print the shortest path (minimum amount of vertices) from vertex A to vertex B.
Current implementation:
public String findPath(int v, int w) {
Queue<Integer> q = new LinkedList<Integer>();
boolean[] visited = new boolean[g.numVertices()];
String[] pathTo = new String[g.numVertices()];
q.add(v);
pathTo[v] = v+" ";
while(q.peek() != null) {
if(runBFS(q.poll(),w,visited,q,pathTo))
break;
}
return pathTo[w];
}
private boolean runBFS(int v, int w, boolean[] visited, Queue<Integer> q, String[] pathTo) {
if(visited[v]) {
}
else if(v == w)
return true;
}
else {
visited[v] = true;
VertexIterator vi = g.adjacentVertices(v);
while(vi.hasNext()) {
int nextVertex = vi.next();
pathTo[nextVertex] = pathTo[v] + nextVertex + " ";
q.add(nextVertex);
}
}
return false;
}
v = vertex of origin
w = target vertex
g = graph
vi = a normal iterator that iterates over the neighbours of v
Right now , it is using String[] to trace the paths but I was suggested that there is a solution to do this with Queue<ArrayList<Integer>> rather than String[] when saving paths by running this queue in parallel with the q queue.
Could someone guide me through this ?
You can use a second queue Queue<ArrayList<Integer>> q2 to store the shortest path (as an ArrayList<Integer>) from v to each node currently in q in the same order. Whenever you poll q, you also poll q2, and whenever you add a node to q, you calculate the shortest path to that node by copying the shortest path to the previous node and appending the current node, and add it to q2.
Note, however, that copying the shortest path may take time linear in the number of vertices, which will increase the overall complexity. For this reason I wouldn't recommend this approach. Instead, for each node n you can store the previous node you came from when you visited n. As soon as you reach the target node w, you can then backtrack through these previous nodes to find the shortest path from the start node.

find longest path of white nodes

This question was asked in an interview:
Tree with black and white nodes is given. Find a longest path of white nodes in the given tree.Is the approach below correct or somebody help with a better approach thanks!
int Longest(node root, int max)
{
if(root==null || root.color == black)
return 0;
if(root.color == white)
{
int curmax =1+ firstlongest(root.child) + secondlongest(root.child);
if(curmax>max)
max = curmax;
return curmax;
}
if(root.color == black)
{
for(all children)
{
int curmax =1+ firstlongest(root.child) + secondlongest(root.child);
}
if(curmax>max)
max =curmax;
return 0;
}
}
int firstlongest(node* child){//will calculate first longest of children and similarly
secondlongest gives second.Finally max will have length of longest path.
Intro:
First remember how to find a longest path in a tree. You take an arbitrary vertex v, find the farthest from it vertex u with bfs, then find the farthest from u vertex t, again with bfs, and (u,t) path will be the longest in the tree. I will not prove it here, you can either google for it or try to prove yourself (it's quite obvious though, if you run it on some examples).
Solution:
Now your problem. We don't need black nodes, so let's throw them away :) The remaining graph will be a forest, i.e. set of trees. Find longest paths for every tree with known algorithm and choose the longest among all.
Complexity:
Described algo will perform one linear pass to remove black nodes, and two linear bfs for each tree in the forest, which are linear to all nodes in graph. Totally: O(n) + O(n+m) + O(n+m) = O(n+m)
Your procedure only seems to compute paths that go down. Assuming all nodes white, it will miss the longest path in this tree:
r
/
a
/ \
b c
/ \
d e
The longest path is dbace.
The code seems incorrect for me. The following section:
if(root.color == black)
{
for(all children)
{
int curmax = max(longest(root.child[i], max));
}
if(curmax>max)
max =curmax;
return 0;
}
will never be executed, because if root.color == black method will return 0 earlier.
Here is how I would do this:
private static int longestWhitePathFromRootLength (Node node)
{
if (node.color == BLACK)
return 0;
else // node.color == WHITE
{
int l = 0;
for (Node n: node.children)
{
l = Math.max (l, longestWhitePathFromRootLength (n));
}
return l + 1;
}
}
public static int longestWhitePathLength (Node node)
{
int l = 0;
for (Node n: node.children)
{
l = Math.max (l, longestWhitePathLength (n));
}
return Math.max (l, longestWhitePathFromRootLength (node));
}

Counting the number of edges traversed in a Breadth First Search?

This is my bfs algorithim. I want to store the number of edges i traversed in the field edges, but I can't figure out where to place the variable to add one for each edge. I keep getting answers that are too long, so i think this is harder than simply incrementing edge.
It should be noted that this is supposed to calculate the edges along the true path only, not the extra edges.
public int distance(Vertex x, Vertex y){
Queue<Vertex> search = new LinkedList<Vertex>();
search.add(x);
x.visited = true;
while(!search.isEmpty()){
Vertex t = search.poll();
if(t == y){
return edges;
}
for(Vertex n: t.neighbours){
if(!n.visited){
n.visited = true;
search.add(n);
}
}
System.out.println(search + " " + t);
}
return edges;
}
Any and all help is appreciated. if you require more classes/methods let me know
EDIT
import java.util.ArrayList;
public class Vertex {
public static char currentID = 'a';
protected ArrayList<Vertex> neighbours;
protected char id;
protected boolean visited = false;
protected Vertex cameFrom = null;
public Vertex(){
neighbours = new ArrayList<Vertex>();
id = currentID;
currentID++;
Graph.all.add(this);
}
public void addNeighbour(Vertex x){
int a;
while(x == this){
a = (int) (Math.random()*(Graph.all.size()));
x = Graph.all.get(a);
}
if(!(neighbours.contains(x))){
neighbours.add(x);
x.addNeighbour(this);
//System.out.println(this + " Linking to " + x);
}
}
public void printNeighbours(){
System.out.println("The neighbours of: " + id + " are: " + neighbours);
}
public String toString(){
return id + "";
}
}
In your Vertex class, create a Vertex cameFrom field which you set to point to the Vertex you came from when that node was visited. You could even replace your boolean visited field with this (if it is null the Vertex hasn't been visited yet).
Then, when you find the Vertex y just follow the pointers back to Vertex x counting how many steps it takes as you go.
If you don't want to change your Vertex class, then just keep a Map<Vertex,Vertex> during your search which stores the mappings from the vertex you're visiting to the vertex you came from. When you get to the end you can follow the path to the beginning in the same way.
Something along these lines perhaps:
public int distance(Vertex x, Vertex y){
Queue<Vertex> search = new LinkedList<Vertex>();
search.add(x);
while(!search.isEmpty()){
Vertex t = search.poll();
if(t == y){
return pathLength( t );
}
for(Vertex n: t.neighbours){
if(n.cameFrom == null || n != x){
n.cameFrom = t;
search.add(n);
}
}
System.out.println(search + " " + t);
}
return -1;
}
public int pathLength( Vertex v )
{
int path = 0;
while ( v.cameFrom != null )
{
v = v.cameFrom;
path++;
}
return path;
}
In this example, the number of edges is simply the size of the search. queue.
EDIT:
One possible solution is to do it layer by layer. Lets say you asked for the distance between Vertex A, F
and the Graph looks like:
A
|\
B C
|
D
|\
E F
First calculate the distance between A and B,C (which is easy because B and C are immediate neighbors of A. Then calculate the distance between A and D (which is easy because D is an immediate neighbor of B, then A and E, F. Store the distance in the A vertex node. Now after you've run the BFS and determined the search result, you can simply ask for the distance. Look at this visual diagram.

Categories

Resources