mirror of
https://github.com/TheAlgorithms/Java.git
synced 2025-07-27 06:23:08 +08:00
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -64,13 +64,10 @@ public class A_Star {
|
||||
|
||||
private int distance; // distance advanced so far.
|
||||
private ArrayList<Integer> path; // list of visited nodes in this path.
|
||||
private int estimated; // heuristic value associated to the last node od the path (current node).
|
||||
private int
|
||||
estimated; // heuristic value associated to the last node od the path (current node).
|
||||
|
||||
public PathAndDistance(
|
||||
int distance,
|
||||
ArrayList<Integer> path,
|
||||
int estimated
|
||||
) {
|
||||
public PathAndDistance(int distance, ArrayList<Integer> path, int estimated) {
|
||||
this.distance = distance;
|
||||
this.path = path;
|
||||
this.estimated = estimated;
|
||||
@ -90,25 +87,16 @@ public class A_Star {
|
||||
|
||||
private void printSolution() {
|
||||
if (this.path != null) {
|
||||
System.out.println(
|
||||
"Optimal path: " +
|
||||
this.path +
|
||||
", distance: " +
|
||||
this.distance
|
||||
);
|
||||
System.out.println("Optimal path: " + this.path + ", distance: " + this.distance);
|
||||
} else {
|
||||
System.out.println(
|
||||
"There is no path available to connect the points"
|
||||
);
|
||||
System.out.println("There is no path available to connect the points");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeGraph(Graph graph, ArrayList<Integer> data) {
|
||||
for (int i = 0; i < data.size(); i += 4) {
|
||||
graph.addEdge(
|
||||
new Edge(data.get(i), data.get(i + 1), data.get(i + 2))
|
||||
);
|
||||
graph.addEdge(new Edge(data.get(i), data.get(i + 1), data.get(i + 2)));
|
||||
}
|
||||
/*
|
||||
.x. node
|
||||
@ -165,123 +153,24 @@ public class A_Star {
|
||||
};
|
||||
|
||||
Graph graph = new Graph(20);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
0,
|
||||
19,
|
||||
75,
|
||||
null,
|
||||
0,
|
||||
15,
|
||||
140,
|
||||
null,
|
||||
0,
|
||||
16,
|
||||
118,
|
||||
null,
|
||||
19,
|
||||
12,
|
||||
71,
|
||||
null,
|
||||
12,
|
||||
15,
|
||||
151,
|
||||
null,
|
||||
16,
|
||||
9,
|
||||
111,
|
||||
null,
|
||||
9,
|
||||
10,
|
||||
70,
|
||||
null,
|
||||
10,
|
||||
3,
|
||||
75,
|
||||
null,
|
||||
3,
|
||||
2,
|
||||
120,
|
||||
null,
|
||||
2,
|
||||
14,
|
||||
146,
|
||||
null,
|
||||
2,
|
||||
13,
|
||||
138,
|
||||
null,
|
||||
2,
|
||||
6,
|
||||
115,
|
||||
null,
|
||||
15,
|
||||
14,
|
||||
80,
|
||||
null,
|
||||
15,
|
||||
5,
|
||||
99,
|
||||
null,
|
||||
14,
|
||||
13,
|
||||
97,
|
||||
null,
|
||||
5,
|
||||
1,
|
||||
211,
|
||||
null,
|
||||
13,
|
||||
1,
|
||||
101,
|
||||
null,
|
||||
6,
|
||||
1,
|
||||
160,
|
||||
null,
|
||||
1,
|
||||
17,
|
||||
85,
|
||||
null,
|
||||
17,
|
||||
7,
|
||||
98,
|
||||
null,
|
||||
7,
|
||||
4,
|
||||
86,
|
||||
null,
|
||||
17,
|
||||
18,
|
||||
142,
|
||||
null,
|
||||
18,
|
||||
8,
|
||||
92,
|
||||
null,
|
||||
8,
|
||||
11,
|
||||
87
|
||||
)
|
||||
);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(Arrays.asList(0, 19, 75, null, 0, 15, 140,
|
||||
null, 0, 16, 118, null, 19, 12, 71, null, 12, 15, 151, null, 16, 9, 111, null, 9, 10,
|
||||
70, null, 10, 3, 75, null, 3, 2, 120, null, 2, 14, 146, null, 2, 13, 138, null, 2, 6,
|
||||
115, null, 15, 14, 80, null, 15, 5, 99, null, 14, 13, 97, null, 5, 1, 211, null, 13, 1,
|
||||
101, null, 6, 1, 160, null, 1, 17, 85, null, 17, 7, 98, null, 7, 4, 86, null, 17, 18,
|
||||
142, null, 18, 8, 92, null, 8, 11, 87));
|
||||
initializeGraph(graph, graphData);
|
||||
|
||||
PathAndDistance solution = aStar(3, 1, graph, heuristic);
|
||||
solution.printSolution();
|
||||
}
|
||||
|
||||
public static PathAndDistance aStar(
|
||||
int from,
|
||||
int to,
|
||||
Graph graph,
|
||||
int[] heuristic
|
||||
) {
|
||||
public static PathAndDistance aStar(int from, int to, Graph graph, int[] heuristic) {
|
||||
// nodes are prioritised by the less value of the current distance of their paths, and the
|
||||
// estimated value
|
||||
// given by the heuristic function to reach the destination point from the current point.
|
||||
PriorityQueue<PathAndDistance> queue = new PriorityQueue<>(
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated()))
|
||||
);
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated())));
|
||||
|
||||
// dummy data to start the algorithm from the beginning point
|
||||
queue.add(new PathAndDistance(0, new ArrayList<>(List.of(from)), 0));
|
||||
@ -290,34 +179,25 @@ public class A_Star {
|
||||
PathAndDistance currentData = new PathAndDistance(-1, null, -1);
|
||||
while (!queue.isEmpty() && !solutionFound) {
|
||||
currentData = queue.poll(); // first in the queue, best node so keep exploring.
|
||||
int currentPosition = currentData
|
||||
.getPath()
|
||||
.get(currentData.getPath().size() - 1); // current node.
|
||||
int currentPosition
|
||||
= currentData.getPath().get(currentData.getPath().size() - 1); // current node.
|
||||
if (currentPosition == to) {
|
||||
solutionFound = true;
|
||||
} else {
|
||||
for (Edge edge : graph.getNeighbours(currentPosition)) {
|
||||
if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(
|
||||
currentData.getPath()
|
||||
);
|
||||
updatedPath.add(edge.getTo()); // Add the new node to the path, update the distance,
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(currentData.getPath());
|
||||
updatedPath.add(
|
||||
edge.getTo()); // Add the new node to the path, update the distance,
|
||||
// and the heuristic function value associated to that path.
|
||||
queue.add(
|
||||
new PathAndDistance(
|
||||
currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath,
|
||||
heuristic[edge.getTo()]
|
||||
)
|
||||
);
|
||||
queue.add(new PathAndDistance(currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath, heuristic[edge.getTo()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (solutionFound)
|
||||
? currentData
|
||||
: new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and its
|
||||
// distance
|
||||
return (solutionFound) ? currentData : new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and
|
||||
// its distance
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs in form of edges which have
|
||||
start vertex, end vertex and weights. Vertices should be labelled with a number between 0 and total number of vertices-1,both inclusive*/{
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs
|
||||
in form of edges which have start vertex, end vertex and weights. Vertices should be labelled with a
|
||||
number between 0 and total number of vertices-1,both inclusive*/
|
||||
{
|
||||
|
||||
int vertex, edge;
|
||||
private Edge[] edges;
|
||||
@ -49,7 +51,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
obj.go();
|
||||
}
|
||||
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the class first time. Assumes source vertex is 0 and
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the
|
||||
// class first time. Assumes source vertex is 0 and
|
||||
Scanner sc = new Scanner(System.in); // Grab scanner object for user input
|
||||
int i, v, e, u, ve, w, j, neg = 0;
|
||||
System.out.println("Enter no. of vertices and edges please");
|
||||
@ -63,7 +66,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
w = sc.nextInt();
|
||||
arr[i] = new Edge(u, ve, w);
|
||||
}
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance
|
||||
// between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -73,10 +77,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[0] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -84,10 +86,7 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
@ -113,9 +112,13 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
* @param end Ending vertex
|
||||
* @param Edge Array of edges
|
||||
*/
|
||||
public void show(int source, int end, Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray() method // Just shows results of computation, if graph is passed to it. The graph should
|
||||
public void show(int source, int end,
|
||||
Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray()
|
||||
// method // Just shows results of computation, if graph is passed to it. The
|
||||
// graph should
|
||||
int i, j, v = vertex, e = edge, neg = 0;
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path
|
||||
// distance between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -125,10 +128,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[source] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -136,10 +137,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
|
@ -17,11 +17,7 @@ import java.util.Arrays;
|
||||
public class BipartiteGrapfDFS {
|
||||
|
||||
private static boolean bipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj,
|
||||
int[] color,
|
||||
int node
|
||||
) {
|
||||
int V, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
|
||||
if (color[node] == -1) {
|
||||
color[node] = 1;
|
||||
}
|
||||
@ -38,10 +34,7 @@ public class BipartiteGrapfDFS {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isBipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj
|
||||
) {
|
||||
public static boolean isBipartite(int V, ArrayList<ArrayList<Integer>> adj) {
|
||||
// Code here
|
||||
int[] color = new int[V + 1];
|
||||
Arrays.fill(color, -1);
|
||||
@ -57,9 +50,7 @@ public class BipartiteGrapfDFS {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
BufferedReader read = new BufferedReader(
|
||||
new InputStreamReader(System.in)
|
||||
);
|
||||
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
|
||||
int t = Integer.parseInt(read.readLine().trim());
|
||||
while (t-- > 0) {
|
||||
String[] S = read.readLine().trim().split(" ");
|
||||
|
@ -137,11 +137,7 @@ public class ConnectedComponent {
|
||||
graphInts.addEdge(8, 10);
|
||||
graphInts.addEdge(10, 8);
|
||||
|
||||
System.out.println(
|
||||
"Amount of different char-graphs: " + graphChars.countGraphs()
|
||||
);
|
||||
System.out.println(
|
||||
"Amount of different int-graphs: " + graphInts.countGraphs()
|
||||
);
|
||||
System.out.println("Amount of different char-graphs: " + graphChars.countGraphs());
|
||||
System.out.println("Amount of different int-graphs: " + graphInts.countGraphs());
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ class Cycle {
|
||||
visited[i] = false;
|
||||
}
|
||||
|
||||
System.out.println(
|
||||
"Enter the details of each edges <Start Node> <End Node>"
|
||||
);
|
||||
System.out.println("Enter the details of each edges <Start Node> <End Node>");
|
||||
|
||||
for (int i = 0; i < edges; i++) {
|
||||
int start, end;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/
|
||||
for better understanding
|
||||
for better understanding
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -45,12 +45,8 @@ class dijkstras {
|
||||
Set[u] = true;
|
||||
|
||||
for (int v = 0; v < k; v++) {
|
||||
if (
|
||||
!Set[v] &&
|
||||
graph[u][v] != 0 &&
|
||||
dist[u] != Integer.MAX_VALUE &&
|
||||
dist[u] + graph[u][v] < dist[v]
|
||||
) {
|
||||
if (!Set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE
|
||||
&& dist[u] + graph[u][v] < dist[v]) {
|
||||
dist[v] = dist[u] + graph[u][v];
|
||||
}
|
||||
}
|
||||
@ -61,23 +57,23 @@ class dijkstras {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 4, 0, 0, 0, 0, 0, 8, 0 },
|
||||
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
|
||||
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
|
||||
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
|
||||
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
|
||||
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
|
||||
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
|
||||
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 },
|
||||
{0, 4, 0, 0, 0, 0, 0, 8, 0},
|
||||
{4, 0, 8, 0, 0, 0, 0, 11, 0},
|
||||
{0, 8, 0, 7, 0, 4, 0, 0, 2},
|
||||
{0, 0, 7, 0, 9, 14, 0, 0, 0},
|
||||
{0, 0, 0, 9, 0, 10, 0, 0, 0},
|
||||
{0, 0, 4, 14, 10, 0, 2, 0, 0},
|
||||
{0, 0, 0, 0, 0, 2, 0, 1, 6},
|
||||
{8, 11, 0, 0, 0, 0, 1, 0, 7},
|
||||
{0, 0, 2, 0, 0, 0, 6, 7, 0},
|
||||
};
|
||||
dijkstras t = new dijkstras();
|
||||
t.dijkstra(graph, 0);
|
||||
} //main
|
||||
} //djikstras
|
||||
} // main
|
||||
} // djikstras
|
||||
/*
|
||||
OUTPUT :
|
||||
Vertex Distance
|
||||
Vertex Distance
|
||||
0 0
|
||||
1 4
|
||||
2 12
|
||||
|
@ -9,42 +9,32 @@ public class FloydWarshall {
|
||||
public static final int INFINITY = 999;
|
||||
|
||||
public FloydWarshall(int numberofvertices) {
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices + 1]; // stores the value of distance from all the possible path form the source
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices
|
||||
+ 1]; // stores the value of distance from all the possible path form the source
|
||||
// vertex to destination vertex
|
||||
// The matrix is initialized with 0's by default
|
||||
this.numberofvertices = numberofvertices;
|
||||
}
|
||||
|
||||
public void floydwarshall(int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
public void floydwarshall(
|
||||
int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
DistanceMatrix[source][destination] =
|
||||
AdjacencyMatrix[source][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination];
|
||||
}
|
||||
}
|
||||
for (
|
||||
int intermediate = 1;
|
||||
intermediate <= numberofvertices;
|
||||
intermediate++
|
||||
) {
|
||||
for (int intermediate = 1; intermediate <= numberofvertices; intermediate++) {
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
if (
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination] <
|
||||
DistanceMatrix[source][destination]
|
||||
) { // calculated distance it get replaced as new shortest distance // if the new distance calculated is less then the earlier shortest
|
||||
DistanceMatrix[source][destination] =
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
if (DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination]
|
||||
< DistanceMatrix[source]
|
||||
[destination]) { // calculated distance it get replaced as
|
||||
// new shortest distance // if the new
|
||||
// distance calculated is less then the
|
||||
// earlier shortest
|
||||
DistanceMatrix[source][destination] = DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,11 +45,7 @@ public class FloydWarshall {
|
||||
System.out.println();
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
System.out.print(source + "\t");
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
System.out.print(DistanceMatrix[source][destination] + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
@ -70,15 +56,10 @@ public class FloydWarshall {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
System.out.println("Enter the number of vertices");
|
||||
int numberOfVertices = scan.nextInt();
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices +
|
||||
1][numberOfVertices + 1];
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices + 1][numberOfVertices + 1];
|
||||
System.out.println("Enter the Weighted Matrix for the graph");
|
||||
for (int source = 1; source <= numberOfVertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberOfVertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberOfVertices; destination++) {
|
||||
adjacencyMatrix[source][destination] = scan.nextInt();
|
||||
if (source == destination) {
|
||||
adjacencyMatrix[source][destination] = 0;
|
||||
|
@ -21,7 +21,7 @@ public class HamiltonianCycle {
|
||||
this.V = graph.length;
|
||||
this.cycle = new int[this.V + 1];
|
||||
|
||||
//Initialize path array with -1 value
|
||||
// Initialize path array with -1 value
|
||||
for (int i = 0; i < this.cycle.length; i++) {
|
||||
this.cycle[i] = -1;
|
||||
}
|
||||
@ -41,13 +41,15 @@ public class HamiltonianCycle {
|
||||
return cycle;
|
||||
}
|
||||
|
||||
/** function to find paths recursively
|
||||
/**
|
||||
* function to find paths recursively
|
||||
* Find paths recursively from given vertex
|
||||
* @param vertex Vertex from which path is to be found
|
||||
* @returns true if path is found false otherwise
|
||||
*/
|
||||
public boolean isPathFound(int vertex) {
|
||||
boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
boolean isLastVertexConnectedToStart
|
||||
= this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
if (isLastVertexConnectedToStart) {
|
||||
return true;
|
||||
}
|
||||
@ -83,7 +85,8 @@ public class HamiltonianCycle {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** function to check if path is already selected
|
||||
/**
|
||||
* function to check if path is already selected
|
||||
* Check if path is already selected
|
||||
* @param vertex Starting vertex
|
||||
*/
|
||||
|
@ -133,7 +133,7 @@ class TopologicalSort<E extends Comparable<E>> {
|
||||
public class KahnsAlgorithm {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//Graph definition and initialization
|
||||
// Graph definition and initialization
|
||||
AdjacencyList<String> graph = new AdjacencyList<>();
|
||||
graph.addEdge("a", "b");
|
||||
graph.addEdge("c", "a");
|
||||
@ -144,7 +144,7 @@ public class KahnsAlgorithm {
|
||||
|
||||
TopologicalSort<String> topSort = new TopologicalSort<>(graph);
|
||||
|
||||
//Printing the order
|
||||
// Printing the order
|
||||
for (String s : topSort.topSortOrder()) {
|
||||
System.out.print(s + " ");
|
||||
}
|
||||
|
@ -7,17 +7,18 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Kosaraju Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the transpose
|
||||
graph (same graph with all the edges reversed) has exactly the same SCCs as the original graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the
|
||||
transpose graph (same graph with all the edges reversed) has exactly the same SCCs as the original
|
||||
graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
|
||||
@ -26,19 +27,20 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
v / v \ /
|
||||
1 5 --> 6
|
||||
1 5 --> 6
|
||||
|
||||
For the above graph, the SCC list goes as follows:
|
||||
0, 1, 2
|
||||
0, 1, 2
|
||||
3
|
||||
4, 5, 6
|
||||
7
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges sorted by lowest finish time.
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges
|
||||
sorted by lowest finish time.
|
||||
2. Find the transpose graph by reversing the edges.
|
||||
3. Pop nodes one by one from the stack and again to DFS on the modified graph.
|
||||
|
||||
@ -48,7 +50,7 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
| v | v v
|
||||
1 5 <--- 6
|
||||
1 5 <--- 6
|
||||
|
||||
We can observe that this graph has the same SCC as that of original graph.
|
||||
|
||||
@ -59,33 +61,33 @@ public class Kosaraju {
|
||||
// Sort edges according to lowest finish time
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
|
||||
//Store each component
|
||||
// Store each component
|
||||
private List<Integer> scc = new ArrayList<>();
|
||||
|
||||
//All the strongly connected components
|
||||
// All the strongly connected components
|
||||
private List<List<Integer>> sccsList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param list Adjacency list of graph
|
||||
* @return List of SCCs
|
||||
*/
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list){
|
||||
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list) {
|
||||
|
||||
sortEdgesByLowestFinishTime(v, list);
|
||||
|
||||
|
||||
List<List<Integer>> transposeGraph = createTransposeMatrix(v, list);
|
||||
|
||||
findStronglyConnectedComponents(v, transposeGraph);
|
||||
|
||||
|
||||
return sccsList;
|
||||
}
|
||||
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list){
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list) {
|
||||
int[] vis = new int[v];
|
||||
for (int i = 0; i < v; i++) {
|
||||
if(vis[i] == 0){
|
||||
if (vis[i] == 0) {
|
||||
dfs(i, vis, list);
|
||||
}
|
||||
}
|
||||
@ -105,15 +107,15 @@ public class Kosaraju {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param transposeGraph Transpose of the given adjacency list
|
||||
*/
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph){
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph) {
|
||||
int[] vis = new int[v];
|
||||
while (!stack.isEmpty()) {
|
||||
var node = stack.pop();
|
||||
if(vis[node] == 0){
|
||||
if (vis[node] == 0) {
|
||||
dfs2(node, vis, transposeGraph);
|
||||
sccsList.add(scc);
|
||||
scc = new ArrayList<>();
|
||||
@ -121,24 +123,21 @@ public class Kosaraju {
|
||||
}
|
||||
}
|
||||
|
||||
//Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs(neighbour, vis, list);
|
||||
}
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
//Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs2(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs2(neighbour, vis, list);
|
||||
}
|
||||
scc.add(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import java.util.PriorityQueue;
|
||||
|
||||
public class Kruskal {
|
||||
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number of
|
||||
// vertices
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number
|
||||
// of vertices
|
||||
private static class Edge {
|
||||
|
||||
private int from;
|
||||
@ -30,12 +30,7 @@ public class Kruskal {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEdge(
|
||||
HashSet<Edge>[] graph,
|
||||
int from,
|
||||
int to,
|
||||
int weight
|
||||
) {
|
||||
private static void addEdge(HashSet<Edge>[] graph, int from, int to, int weight) {
|
||||
graph[from].add(new Edge(from, to, weight));
|
||||
}
|
||||
|
||||
@ -58,9 +53,7 @@ public class Kruskal {
|
||||
System.out.println("Initial Graph: ");
|
||||
for (int i = 0; i < graph.length; i++) {
|
||||
for (Edge edge : graph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +63,7 @@ public class Kruskal {
|
||||
System.out.println("\nMinimal Graph: ");
|
||||
for (int i = 0; i < solGraph.length; i++) {
|
||||
for (Edge edge : solGraph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,9 +74,8 @@ public class Kruskal {
|
||||
// captain of i, stores the set with all the connected nodes to i
|
||||
HashSet<Integer>[] connectedGroups = new HashSet[nodes];
|
||||
HashSet<Edge>[] minGraph = new HashSet[nodes];
|
||||
PriorityQueue<Edge> edges = new PriorityQueue<>(
|
||||
(Comparator.comparingInt(edge -> edge.weight))
|
||||
);
|
||||
PriorityQueue<Edge> edges
|
||||
= new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight)));
|
||||
for (int i = 0; i < nodes; i++) {
|
||||
minGraph[i] = new HashSet<>();
|
||||
connectedGroups[i] = new HashSet<>();
|
||||
@ -98,18 +88,12 @@ public class Kruskal {
|
||||
while (connectedElements != nodes && !edges.isEmpty()) {
|
||||
Edge edge = edges.poll();
|
||||
// This if avoids cycles
|
||||
if (
|
||||
!connectedGroups[captain[edge.from]].contains(edge.to) &&
|
||||
!connectedGroups[captain[edge.to]].contains(edge.from)
|
||||
) {
|
||||
if (!connectedGroups[captain[edge.from]].contains(edge.to)
|
||||
&& !connectedGroups[captain[edge.to]].contains(edge.from)) {
|
||||
// merge sets of the captains of each point connected by the edge
|
||||
connectedGroups[captain[edge.from]].addAll(
|
||||
connectedGroups[captain[edge.to]]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].addAll(connectedGroups[captain[edge.to]]);
|
||||
// update captains of the elements merged
|
||||
connectedGroups[captain[edge.from]].forEach(i ->
|
||||
captain[i] = captain[edge.from]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].forEach(i -> captain[i] = captain[edge.from]);
|
||||
// add Edge to minimal graph
|
||||
addEdge(minGraph, edge.from, edge.to, edge.weight);
|
||||
// count how many elements have been merged
|
||||
|
@ -71,9 +71,7 @@ class AdjacencyMatrixGraph {
|
||||
public AdjacencyMatrixGraph(int givenNumberOfVertices) {
|
||||
this.setNumberOfVertices(givenNumberOfVertices);
|
||||
this.setNumberOfEdges(0);
|
||||
this.setAdjacency(
|
||||
new int[givenNumberOfVertices][givenNumberOfVertices]
|
||||
);
|
||||
this.setAdjacency(new int[givenNumberOfVertices][givenNumberOfVertices]);
|
||||
for (int i = 0; i < givenNumberOfVertices; i++) {
|
||||
for (int j = 0; j < givenNumberOfVertices; j++) {
|
||||
this.adjacency()[i][j] = AdjacencyMatrixGraph.EDGE_NONE;
|
||||
@ -247,11 +245,7 @@ class AdjacencyMatrixGraph {
|
||||
* has been visited
|
||||
* @param orderList the list to add vertices to as they are visited
|
||||
*/
|
||||
private void depthFirstOrder(
|
||||
int currentVertex,
|
||||
boolean[] visited,
|
||||
List<Integer> orderList
|
||||
) {
|
||||
private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> orderList) {
|
||||
// If this vertex has already been visited, do nothing and return
|
||||
if (visited[currentVertex]) {
|
||||
return;
|
||||
@ -264,11 +258,9 @@ class AdjacencyMatrixGraph {
|
||||
|
||||
// Get the adjacency array for this vertex
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int i = 0;
|
||||
i < adjacent.length;
|
||||
i++
|
||||
) { // we are considering exploring, recurse on it // If an edge exists between the currentVertex and the vertex
|
||||
for (int i = 0; i < adjacent.length;
|
||||
i++) { // we are considering exploring, recurse on it // If an edge exists between the
|
||||
// currentVertex and the vertex
|
||||
if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
depthFirstOrder(i, visited, orderList);
|
||||
}
|
||||
@ -317,11 +309,9 @@ class AdjacencyMatrixGraph {
|
||||
// Get the adjacency array for the currentVertex and
|
||||
// check each node
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int vertex = 0;
|
||||
vertex < adjacent.length;
|
||||
vertex++
|
||||
) { // vertex we are considering exploring, we add it to the queue // If an edge exists between the current vertex and the
|
||||
for (int vertex = 0; vertex < adjacent.length;
|
||||
vertex++) { // vertex we are considering exploring, we add it to the queue // If an
|
||||
// edge exists between the current vertex and the
|
||||
if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
queue.add(vertex);
|
||||
}
|
||||
|
@ -31,9 +31,7 @@ class PrimMST {
|
||||
void printMST(int[] parent, int n, int[][] graph) {
|
||||
System.out.println("Edge Weight");
|
||||
for (int i = 1; i < V; i++) {
|
||||
System.out.println(
|
||||
parent[i] + " - " + i + " " + graph[i][parent[i]]
|
||||
);
|
||||
System.out.println(parent[i] + " - " + i + " " + graph[i][parent[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,17 +70,12 @@ class PrimMST {
|
||||
// Update key value and parent index of the adjacent
|
||||
// vertices of the picked vertex. Consider only those
|
||||
// vertices which are not yet included in MST
|
||||
for (
|
||||
int v = 0;
|
||||
v < V;
|
||||
v++
|
||||
) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is false for vertices not yet included in MST // graph[u][v] is non zero only for adjacent vertices of m
|
||||
for (int v = 0; v < V;
|
||||
v++) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is
|
||||
// false for vertices not yet included in MST // graph[u][v] is non zero only
|
||||
// for adjacent vertices of m
|
||||
{
|
||||
if (
|
||||
graph[u][v] != 0 &&
|
||||
!mstSet[v] &&
|
||||
graph[u][v] < key[v]
|
||||
) {
|
||||
if (graph[u][v] != 0 && !mstSet[v] && graph[u][v] < key[v]) {
|
||||
parent[v] = u;
|
||||
key[v] = graph[u][v];
|
||||
}
|
||||
@ -104,11 +97,11 @@ class PrimMST {
|
||||
9 */
|
||||
PrimMST t = new PrimMST();
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 2, 0, 6, 0 },
|
||||
{ 2, 0, 3, 8, 5 },
|
||||
{ 0, 3, 0, 0, 7 },
|
||||
{ 6, 8, 0, 0, 9 },
|
||||
{ 0, 5, 7, 9, 0 },
|
||||
{0, 2, 0, 6, 0},
|
||||
{2, 0, 3, 8, 5},
|
||||
{0, 3, 0, 0, 7},
|
||||
{6, 8, 0, 0, 9},
|
||||
{0, 5, 7, 9, 0},
|
||||
};
|
||||
|
||||
// Print the solution
|
||||
|
@ -8,16 +8,16 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Tarjan's Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
0 --------> 1 -------> 3 --------> 4
|
||||
@ -38,24 +38,25 @@ import java.util.Stack;
|
||||
1, 2, 0
|
||||
3
|
||||
4
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including the head)
|
||||
and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be used).
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including
|
||||
the head) and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be
|
||||
used).
|
||||
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s algorithm does
|
||||
the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s
|
||||
algorithm does the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
|
||||
*/
|
||||
public class TarjansAlgorithm {
|
||||
|
||||
//Timer for tracking lowtime and insertion time
|
||||
// Timer for tracking lowtime and insertion time
|
||||
private int Time;
|
||||
|
||||
private List<List<Integer>> SCClist = new ArrayList<List<Integer>>();
|
||||
@ -66,15 +67,15 @@ public class TarjansAlgorithm {
|
||||
|
||||
// insertionTime:Time when a node is visited 1st time while DFS traversal
|
||||
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time) that can
|
||||
// be reached from a subtree rooted with a particular node.
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time)
|
||||
// that can be reached from a subtree rooted with a particular node.
|
||||
int[] lowTime = new int[V];
|
||||
int[] insertionTime = new int[V];
|
||||
for (int i = 0; i < V; i++) {
|
||||
insertionTime[i] = -1;
|
||||
lowTime[i] = -1;
|
||||
}
|
||||
|
||||
|
||||
// To check if element is present in stack
|
||||
boolean[] isInStack = new boolean[V];
|
||||
|
||||
@ -90,36 +91,36 @@ public class TarjansAlgorithm {
|
||||
}
|
||||
|
||||
private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime,
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
|
||||
// Initialize insertion time and lowTime value of current node
|
||||
insertionTime[u] = Time;
|
||||
lowTime[u] = Time;
|
||||
Time += 1;
|
||||
|
||||
//Push current node into stack
|
||||
// Push current node into stack
|
||||
isInStack[u] = true;
|
||||
st.push(u);
|
||||
|
||||
// Go through all vertices adjacent to this
|
||||
for (Integer vertex : graph.get(u)) {
|
||||
//If the adjacent node is unvisited, do DFS
|
||||
// If the adjacent node is unvisited, do DFS
|
||||
if (insertionTime[vertex] == -1) {
|
||||
stronglyConnCompsUtil(vertex, lowTime, insertionTime, isInStack, st, graph);
|
||||
//update lowTime for the current node comparing lowtime of adj node
|
||||
// update lowTime for the current node comparing lowtime of adj node
|
||||
lowTime[u] = Math.min(lowTime[u], lowTime[vertex]);
|
||||
} else if (isInStack[vertex]) {
|
||||
//If adj node is in stack, update low
|
||||
// If adj node is in stack, update low
|
||||
lowTime[u] = Math.min(lowTime[u], insertionTime[vertex]);
|
||||
}
|
||||
}
|
||||
//If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
// If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
if (lowTime[u] == insertionTime[u]) {
|
||||
int w = -1;
|
||||
var scc = new ArrayList<Integer>();
|
||||
|
||||
//Stack has all the nodes of the current SCC
|
||||
// Stack has all the nodes of the current SCC
|
||||
while (w != u) {
|
||||
w = st.pop();
|
||||
scc.add(w);
|
||||
@ -128,5 +129,4 @@ public class TarjansAlgorithm {
|
||||
SCClist.add(scc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user