“This is my 39th day of participating in the First Challenge 2022. For more details: First Challenge 2022.”
Minimum spanning tree algorithm Kruskal
1, analysis,
The so-called minimum spanning tree is the minimum value of the sum of all edges without affecting the connectivity of all nodes
Look at all edges, from smallest to largest (greedy), if the current edge does not form a ring, take this edge, if the current edge does form a ring, leave this edge
And search sets go up: join in turn, merge in turn
And look up the set and skip the process, will not look up the set chapter
2, implementation,
// Union-Find Set
public static class UnionFind {
// key Specifies the node above the value key node
private HashMap<Node, Node> fatherMap;
// key Specifies the number of nodes in a set. Value Specifies the number of nodes in the set
private HashMap<Node, Integer> sizeMap;
public UnionFind(a) {
fatherMap = new HashMap<>();
sizeMap = new HashMap<>();
}
public void makeSets(Collection<Node> nodes) {
fatherMap.clear();
sizeMap.clear();
for (Node node : nodes) {
fatherMap.put(node, node);
sizeMap.put(node, 1); }}private Node findFather(Node n) {
Stack<Node> path = new Stack<>();
while(n ! = fatherMap.get(n)) { path.add(n); n = fatherMap.get(n); }while(! path.isEmpty()) { fatherMap.put(path.pop(), n); }return n;
}
public boolean isSameSet(Node a, Node b) {
return findFather(a) == findFather(b);
}
public void union(Node a, Node b) {
if (a == null || b == null) {
return;
}
Node aDai = findFather(a);
Node bDai = findFather(b);
if(aDai ! = bDai) {int aSetSize = sizeMap.get(aDai);
int bSetSize = sizeMap.get(bDai);
if (aSetSize <= bSetSize) {
fatherMap.put(aDai, bDai);
sizeMap.put(bDai, aSetSize + bSetSize);
sizeMap.remove(aDai);
} else{ fatherMap.put(bDai, aDai); sizeMap.put(aDai, aSetSize + bSetSize); sizeMap.remove(bDai); }}}}public static class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
returno1.weight - o2.weight; }}public static Set<Edge> kruskalMST(Graph graph) {
UnionFind unionFind = new UnionFind();
unionFind.makeSets(graph.nodes.values());
// From small edge to big edge, pop up one by one, small root heap!
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
for (Edge edge : graph.edges) { / / M side
priorityQueue.add(edge); // O(logM)
}
Set<Edge> result = new HashSet<>();
while(! priorityQueue.isEmpty()) {/ / M side
Edge edge = priorityQueue.poll(); // O(logM)
if(! unionFind.isSameSet(edge.from, edge.to)) {// O(1)result.add(edge); unionFind.union(edge.from, edge.to); }}return result;
}
Copy the code
Prim of minimum spanning tree algorithm
1, analysis,
Select a point and unlock it again
Point -> edge -> point -> edge…
2, implementation,
public static class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
returno1.weight - o2.weight; }}public static Set<Edge> primMST(Graph graph) {
// The unlocked edge goes into the small root heap
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
// Which points are unlocked
HashSet<Node> nodeSet = new HashSet<>();
Set<Edge> result = new HashSet<>(); // The selected edges are in result
for (Node node : graph.nodes.values()) { // Pick a point at random
// Node is the starting point
if(! nodeSet.contains(node)) { nodeSet.add(node);for (Edge edge : node.edges) { // Unlock all connected edges with a single point
priorityQueue.add(edge);
}
while(! priorityQueue.isEmpty()) { Edge edge = priorityQueue.poll();// Eject the smallest edge of the unlocked edge
Node toNode = edge.to; // A possible new point
if(! nodeSet.contains(toNode)) {// If it does not, it is a new point
nodeSet.add(toNode);
result.add(edge);
for(Edge nextEdge : toNode.edges) { priorityQueue.add(nextEdge); }}}}// break; To prevent the forest
}
return result;
}
Copy the code
Third, summary
Minimum spanning trees are all undirected graphs
Minimum spanning Tree Algorithm Kruskal:
- Always start with the edge with the lowest weight and look at the edge with the highest weight
- The current edge either enters the minimum spanning tree set or is discarded
- If the current edge goes into the minimum spanning tree without forming a ring, the current edge is used
- Discard the current edge if it would form a loop if entered into the minimum spanning tree
- After looking at all the edges, we get the set of minimum spanning trees
Minimum spanning tree algorithm Prim:
- You can start at any node to find a minimum spanning tree
- After a point is added to the selected point, it unlocks all new edges starting from that point
- Pick the smallest edge of all the unlocked edges and see if that edge forms a ring
- If so, leave the current edge and proceed to the smallest edge of the remaining unlocked edge. Repeat 3
- If not, take the current edge and add the edge’s point to the selected point, repeat 2
- When all points are selected, the minimum spanning tree is obtained