Skip to content

Instantly share code, notes, and snippets.

@tareq-si-salem
Last active August 6, 2016 17:33
Show Gist options
  • Select an option

  • Save tareq-si-salem/1d4da0676462888823025f14bc1e7d88 to your computer and use it in GitHub Desktop.

Select an option

Save tareq-si-salem/1d4da0676462888823025f14bc1e7d88 to your computer and use it in GitHub Desktop.
Prim-Jarnik and Kruksal to find a Minimal Spanning Tree of a connected graph
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class MST {
public static void main(String[] args) {
Graph G = new Graph();
System.out.println("Cost matrix: ");
for (int i = 0; i < G.V.size(); i++) {
for (int j = 0; j < G.V.size(); j++) {
if (G.getWeight(i, j) == Graph.INF) {
System.out.print(Graph.INF_SYMBOL + "\t");
} else {
System.out.printf("%.0f\t", G.getWeight(i, j));
}
}
System.out.println("");
}
// Start PRIM's Algorithm
prim(G);
// Start
kruskal(G);
}
private static void prim(Graph G) {
System.out.println("--------------------- Prim's Algorithms ---------------------");
int n = G.V.size();
int closest[] = new int[n];
double smallestCosts[] = new double[n];
closest[0] = 0;
for (int i = 1; i < closest.length; i++) {
smallestCosts[i] = G.getWeight(i, 0);
closest[i] = 0;
}
double min;
int k = 0;
System.out.println("Iteration\t\t\t\tClosest\t\t\t\tSmallestCosts");
System.out.println("#Initial\t\t\t" + Arrays.toString(closest) + "\t\t" + Arrays.toString(smallestCosts));
for (int i = 1; i < n; i++) {
min = Graph.INF;
for (int j = 1; j < n; j++) {
if (smallestCosts[j] != 0 && min > smallestCosts[j]) {
k = j;
min = smallestCosts[j];
}
}
// At this stage we have min{ smallesCosts } is smallesCosts[k]
smallestCosts[k] = 0;
for (int j = 1; j < n; j++) {
if (smallestCosts[j] > G.getWeight(k, j)) {
closest[j] = k;
smallestCosts[j] = G.getWeight(k, j);
}
}
System.out.println("#" + i + "\t\t\t\t" + Arrays.toString(closest) + "\t\t" + Arrays.toString(smallestCosts));
}
double totalCost = 0;
for (int i = 0; i < closest.length; i++) {
totalCost += G.getWeight(i, closest[i]);
}
System.out.println("Minimal cost is: " + totalCost);
}
private static void kruskal(Graph G) {
System.out.println("--------------------- Kruksal's Algorithm ---------------------");
ArrayList<Edge> forest = new ArrayList<>(G.E);
visited = new boolean[G.E.size()];
Collections.sort(forest, (itemA, itemB) -> {
return (int) (itemA.weight - itemB.weight);
});
System.out.println(forest);
ArrayList<Edge> tree = new ArrayList<>();
while (!forest.isEmpty()) {
Edge edge = forest.remove(0);
Arrays.fill(visited, false);
boolean path = path_between_u_and_v(tree, edge.u, edge.v);
System.out.println("There's a path between " + edge.u + " and " + edge.v + " :" + path);
if (!path) // if v is a child of u
{
tree.add(edge);
}
System.out.println(tree);
}
double totalCost = 0;
for (Edge edge : tree) {
totalCost += edge.weight;
}
System.out.println("total Cost : " + totalCost);
}
static boolean visited[];
private static boolean path_between_u_and_v(ArrayList<Edge> tree, int u, int v) {
visited[u] = true;
boolean found = false;
if (u == v) {
return true;
}
for (Edge edge : tree) {
if (edge.u == u && !visited[edge.v]) {
if (path_between_u_and_v(tree, edge.v, v)) {
found = true;
}
} else if (edge.v == u && !visited[edge.u]) {
if (path_between_u_and_v(tree, edge.u, v)) {
found = true;
}
}
}
return found;
}
}
class Graph {
ArrayList<Integer> V = new ArrayList<>();
ArrayList<Edge> E = new ArrayList<>();
static final double INF = Double.MAX_VALUE;
static final char INF_SYMBOL = '\u221e';
double getWeight(int u, int v) {
Edge edge = new Edge(u, v, -1); // -1 don't care
int index = E.indexOf(edge);
if (u == v) {
return 0;
}
if (index != -1) {
return E.get(index).weight;
}
return Double.MAX_VALUE;
}
public Graph() {
Scanner in = new Scanner(System.in);
System.out.print("Enter number of nodes: ");
int n = in.nextInt();
for (int u = 0; u < n; u++) {
V.add(u);
System.out.println("Enter adjacent nodes to [" + u + "] (-1 to stop):");
int v;
while ((v = in.nextInt()) != -1) {
Edge edge = new Edge(u, v, in.nextDouble());
E.add(edge);
}
}
System.out.println(E);
}
}
class Edge {
int u, v;
double weight;
public Edge(int u, int v, double weight) {
this.u = u;
this.v = v;
this.weight = weight;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Edge) {
Edge edge = (Edge) obj;
return edge.u == u && edge.v == v || edge.u == v && edge.v == u;
} else {
return super.equals(obj);
}
}
@Override
public String toString() {
return String.format("<%d, %d> %.0f", u, v, weight);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment