Last active
August 6, 2016 17:33
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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