// This Region Contains All The Necessary Functions // To Implement Prim's Algorithm For // The Minimum Spanning Tree #region Spanning Tree Methods // Used To Calculate The Weight Difference Between Two Nodes private static float WeightDifference(PQNode N1, PQNode N2) { byte red1, green1, blue1; byte red2, green2, blue2; // Assigning The RGB Values Of Each Color red1 = N1.currentVertex.red; red2 = N2.currentVertex.red; green1 = N1.currentVertex.green; green2 = N2.currentVertex.green; blue1 = N1.currentVertex.blue; blue2 = N2.currentVertex.blue; // Calculating The Difference Between Them return((float)Math.Sqrt((red2 - red1) * (red2 - red1) + (green2 - green1) * (green2 - green1) + (blue2 - blue1) * (blue2 - blue1))); }
// The Function That Calculates The Minimum Spanning Tree For The Graph // Its Only Parameter Is The List Of Distinct Colors public void MinSpanningTree(List <RGBPixel> LoD) { // Using A Priority Queue So That The Edges Are // Sorted According To Their Weights In Ascending Order // The Priority Queue Contains The Number Of Vertices (LoD.Count) FastPriorityQueue <PQNode> PQ = new FastPriorityQueue <PQNode>(LoD.Count); // An Array That Contains Each Node (color) // And A Pointer To That Node's Parent PQNode[] PQNode = new PQNode[LoD.Count]; // Initialising The First Node In The Array // Its Parent Is Null PQNode[0] = new PQNode(LoD[0], null); // Inserting That First Node Into The Priority Queue // With A Value of 0 PQ.Enqueue(PQNode[0], 0); float weight; // For Each Vertex (Minus The Already Added One), // Insert That Vertex Into The Array // With Parent = null, Then Insert It Into The PQ // With Values = Infinity for (int i = 1; i < LoD.Count; i++) { PQNode[i] = new PQNode(LoD[i], null); PQ.Enqueue(PQNode[i], int.MaxValue); } // Looping Until The Priority Queue Is Empty while (PQ.Count != 0) { // Dequeuing The First (Minimum) Element // From The PQ PQNode Minimum = PQ.Dequeue(); // Checking If The Minimum Element Is The Root Node Or Not // (Only The Root Node Has A Null Parent In The First Iteration) if (Minimum.Parent != null) { Edge edge; edge.src = Minimum.currentVertex; edge.dest = (RGBPixel)Minimum.Parent; edge.weight = (Minimum.currentWeight); MST.Add(edge); // Add the minimum weight to the MST. MSTSum += edge.weight; // Add The Edge's Weight To The MST Sum } // We Have To Modify The Values Of The PQ // Each Time foreach (var node in PQ) { // Calculating The Weight Difference Between The Current Node // And The Minimum Node weight = WeightDifference(node, Minimum); // If That Weight Difference Is Less Than The Node's Current Weight // Then The Minimum Node Becomes The Parent Of That Node // And We Adjust That Node's Weight To The Weight Difference // By Updating The PQ if (weight < node.currentWeight) { node.Parent = Minimum.currentVertex; PQ.UpdatePriority(node, weight); } } } }