programming-examples/java/Hard_Graph_Problems/Java Program to Find the Longest Path in a DAG.java
2019-11-15 12:59:38 +01:00

217 lines
6.9 KiB
Java

import java.util.Scanner;
import java.util.Vector;
class Node
{
int name; // node ID, started from 0 to n-1
Vector<Integer> preds; // predecessors (String)
Vector<Integer> neibs; // neighbors (String)
Vector<Integer> backs; // backward edges -node is end vertex (Integer)
Vector<Integer> fors; // forward edges -node is start vertex (Integer)
int pNode; // previous node on the augmenting path
int pEdge; // from which edge this node comes on the augmenting
// path
public Node(int id)
{
name = id;
backs = new Vector<Integer>();
fors = new Vector<Integer>();
pNode = -1;
pEdge = -1;
}
}
class Edge
{
int name; // edge ID, started from 0 to n-1
int start; // start vertex of this edge
int end; // end vertex of this edge
int direct; // forwards (+1) or backwards (-1) on augmenting path
// if 0 then not part of augmenting path
int capacity; // capacity
int flow; // current flow
public Edge(int id)
{
name = id;
start = -1;
end = -1;
direct = 0; // default is neither
capacity = 0;
flow = 0;
}
public String toString()
{
return name + ": s=" + start + " e=" + end + " d=" + direct;
}
}
public class LongestPathinDAG
{
int n; // number of nodes
int target; // destination node
int minLength; // the minimal length of each path
Node[] v; // used to store Nodes
Edge[] e; // used to store Edges
int[] path; // used to store temporary path
int length = 0; // length of the path
int distance = 0; // distance of the path
int[] bestPath; // used to store temporary path
int bestLength = 0; // length of the longest path
int bestDistance = -1000000; // distance of the longest path
int[] visited; // used to mark a node as visited if set as
// 1
public LongestPathinDAG()
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of vertices: ");
n = sc.nextInt();
System.out.println("Enter the number of edges: ");
int m = sc.nextInt();
v = new Node[n];
e = new Edge[m];
System.out.println(n + " nodes and " + m + " edges.");
for (int i = 0; i < n; i++)
v[i] = new Node(i);
int i = 0;
while (i < e.length)
{
Edge edge = new Edge(i);
int sVal = sc.nextInt();
edge.start = sVal;// sc.nextInt();
int eVal = sc.nextInt();
edge.end = eVal;// sc.nextInt();
edge.capacity = sc.nextInt();
System.out.println(" edge: " + edge.start + " - " + edge.end
+ " : " + edge.capacity);
edge.flow = 0;
e[i] = edge;
v[sVal].fors.add(i);
v[eVal].backs.add(i);
i++;
if (i == m)
break;
}
visited = new int[v.length];
path = new int[v.length];
bestPath = new int[v.length];
sc.close();
}
/*
* this function looks for a longest path starting from being to end,
* using the backtrack depth-first search.
*/
public boolean findLongestPath(int begin, int end, int minLen)
{
/*
* compute a longest path from begin to end
*/
target = end;
bestDistance = -100000000;
minLength = minLen;
dfsLongestPath(begin);
if (bestDistance == -100000000)
return false;
else
return true;
}
private void dfsLongestPath(int current)
{
visited[current] = 1;
path[length++] = current;
if (current == target && length >= minLength)
{
if (distance > bestDistance)
{
for (int i = 0; i < length; i++)
bestPath[i] = path[i];
bestLength = length;
bestDistance = distance;
}
}
else
{
Vector<Integer> fors = v[current].fors;
for (int i = 0; i < fors.size(); i++)
{
Integer edge_obj = (Integer) fors.elementAt(i);
int edge = edge_obj.intValue();
if (visited[e[edge].end] == 0)
{
distance += e[edge].capacity;
dfsLongestPath(e[edge].end);
distance -= e[edge].capacity;
}
}
}
visited[current] = 0;
length--;
}
public String toString()
{
String output = "v" + bestPath[0];
for (int i = 1; i < bestLength; i++)
output = output + " -> v" + bestPath[i];
return output;
}
public static void main(String arg[])
{
LongestPathinDAG lp = new LongestPathinDAG();
/*
* find a longest path from vertex 0 to vertex n-1.
*/
if (lp.findLongestPath(0, lp.n - 1, 1))
System.out.println("Longest Path is " + lp
+ " and the distance is " + lp.bestDistance);
else
System.out.println("No path from v0 to v" + (lp.n - 1));
/*
* find a longest path from vertex 3 to vertex 5.
*/
if (lp.findLongestPath(3, 5, 1))
System.out.println("Longest Path is " + lp
+ " and the distance is " + lp.bestDistance);
else
System.out.println("No path from v3 to v5");
/*
* find a longest path from vertex 5 to vertex 3.
*/
if (lp.findLongestPath(lp.n - 1, 3, 1))
System.out.println("Longest Path is " + lp
+ " and the distance is " + lp.bestDistance);
else
System.out.println("No path from v5 to v3");
}
}
/*
Enter the number of vertices:
6
Enter the number of edges:
7
6 nodes and 7 edges.
0 1 2
edge: 0 - 1 : 2
1 2 3
edge: 1 - 2 : 3
1 3 4
edge: 1 - 3 : 4
3 4 5
edge: 3 - 4 : 5
4 5 6
edge: 4 - 5 : 6
5 3 7
edge: 5 - 3 : 7
5 2 8
edge: 5 - 2 : 8
Longest Path is v0 -> v1 -> v3 -> v4 -> v5 and the distance is 17
Longest Path is v3 -> v4 -> v5 and the distance is 11
Longest Path is v5 -> v3 and the distance is 7