Merge pull request #8222 from pazis/BAEL-3561

BAEL-3561 Prim's Algorithm
This commit is contained in:
Josh Cummings 2019-12-13 15:23:47 -07:00 committed by GitHub
commit e3f63606e1
4 changed files with 269 additions and 0 deletions

View File

@ -0,0 +1,36 @@
package com.baeldung.algorithms.prim;
public class Edge {
private int weight;
private boolean isIncluded = false;
private boolean isPrinted = false;
public Edge(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public boolean isIncluded() {
return isIncluded;
}
public void setIncluded(boolean included) {
isIncluded = included;
}
public boolean isPrinted() {
return isPrinted;
}
public void setPrinted(boolean printed) {
isPrinted = printed;
}
}

View File

@ -0,0 +1,73 @@
package com.baeldung.algorithms.prim;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.math3.util.Pair;
public class Prim {
private List<Vertex> graph;
public Prim(List<Vertex> graph){
this.graph = graph;
}
public void run(){
if (graph.size() > 0){
graph.get(0).setVisited(true);
}
while (isDisconnected()){
Edge nextMinimum = new Edge(Integer.MAX_VALUE);
Vertex nextVertex = graph.get(0);
for (Vertex vertex : graph){
if (vertex.isVisited()){
Pair<Vertex, Edge> candidate = vertex.nextMinimum();
if (candidate.getValue().getWeight() < nextMinimum.getWeight()){
nextMinimum = candidate.getValue();
nextVertex = candidate.getKey();
}
}
}
nextMinimum.setIncluded(true);
nextVertex.setVisited(true);
}
}
private boolean isDisconnected(){
for (Vertex vertex : graph){
if (!vertex.isVisited()){
return true;
}
}
return false;
}
public String originalGraphToString(){
StringBuilder sb = new StringBuilder();
for (Vertex vertex : graph){
sb.append(vertex.originalToString());
}
return sb.toString();
}
public void resetPrintHistory(){
for (Vertex vertex : graph){
Iterator<Map.Entry<Vertex,Edge>> it = vertex.getEdges().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Vertex,Edge> pair = it.next();
pair.getValue().setPrinted(false);
}
}
}
public String minimumSpanningTreeToString(){
StringBuilder sb = new StringBuilder();
for (Vertex vertex : graph){
sb.append(vertex.includedToString());
}
return sb.toString();
}
}

View File

@ -0,0 +1,106 @@
package com.baeldung.algorithms.prim;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.math3.util.Pair;
public class Vertex {
private String label = null;
private Map<Vertex, Edge> edges = new HashMap<>();
private boolean isVisited = false;
public Vertex(String label){
this.label = label;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Map<Vertex, Edge> getEdges() {
return edges;
}
public void addEdge(Vertex vertex, Edge edge){
if (this.edges.containsKey(vertex)){
if (edge.getWeight() < this.edges.get(vertex).getWeight()){
this.edges.replace(vertex, edge);
}
} else {
this.edges.put(vertex, edge);
}
}
public boolean isVisited() {
return isVisited;
}
public void setVisited(boolean visited) {
isVisited = visited;
}
public Pair<Vertex, Edge> nextMinimum(){
Edge nextMinimum = new Edge(Integer.MAX_VALUE);
Vertex nextVertex = this;
Iterator<Map.Entry<Vertex,Edge>> it = edges.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Vertex,Edge> pair = it.next();
if (!pair.getKey().isVisited()){
if (!pair.getValue().isIncluded()) {
if (pair.getValue().getWeight() < nextMinimum.getWeight()) {
nextMinimum = pair.getValue();
nextVertex = pair.getKey();
}
}
}
}
return new Pair<>(nextVertex, nextMinimum);
}
public String originalToString(){
StringBuilder sb = new StringBuilder();
Iterator<Map.Entry<Vertex,Edge>> it = edges.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Vertex,Edge> pair = it.next();
if (!pair.getValue().isPrinted()) {
sb.append(getLabel());
sb.append(" --- ");
sb.append(pair.getValue().getWeight());
sb.append(" --- ");
sb.append(pair.getKey().getLabel());
sb.append("\n");
pair.getValue().setPrinted(true);
}
}
return sb.toString();
}
public String includedToString(){
StringBuilder sb = new StringBuilder();
if (isVisited()) {
Iterator<Map.Entry<Vertex,Edge>> it = edges.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Vertex,Edge> pair = it.next();
if (pair.getValue().isIncluded()) {
if (!pair.getValue().isPrinted()) {
sb.append(getLabel());
sb.append(" --- ");
sb.append(pair.getValue().getWeight());
sb.append(" --- ");
sb.append(pair.getKey().getLabel());
sb.append("\n");
pair.getValue().setPrinted(true);
}
}
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.algorithms.prim;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class PrimUnitTest {
@Test
public void givenAGraph_whenPrimRuns_thenPrintMST() {
Prim prim = new Prim(createGraph());
System.out.println(prim.originalGraphToString());
System.out.println("----------------");
prim.run();
System.out.println();
prim.resetPrintHistory();
System.out.println(prim.minimumSpanningTreeToString());
}
public static List<Vertex> createGraph() {
List<Vertex> graph = new ArrayList<>();
Vertex a = new Vertex("A");
Vertex b = new Vertex("B");
Vertex c = new Vertex("C");
Vertex d = new Vertex("D");
Vertex e = new Vertex("E");
Edge ab = new Edge(2);
a.addEdge(b, ab);
b.addEdge(a, ab);
Edge ac = new Edge(3);
a.addEdge(c, ac);
c.addEdge(a, ac);
Edge bc = new Edge(2);
b.addEdge(c, bc);
c.addEdge(b, bc);
Edge be = new Edge(5);
b.addEdge(e, be);
e.addEdge(b, be);
Edge cd = new Edge(1);
c.addEdge(d, cd);
d.addEdge(c, cd);
Edge ce = new Edge(1);
c.addEdge(e, ce);
e.addEdge(c, ce);
graph.add(a);
graph.add(b);
graph.add(c);
graph.add(d);
graph.add(e);
return graph;
}
}