}//dfs public static void Clustring(int K)// make clustring { /* * Total complexty is O(MST count) = distincit + O(d log K) */ adj_lst = new Dictionary <int, List <int> >(); // initialize adjacency list Node_Cluster = new int[16777216]; // which node assigned to which cluster vis = new bool[16777216]; // visited array described before RGBPixel Val; int sz1 = MST.Count; for (int i = 1; i < sz1; i++) // mov in size of mst = d { if (VX.ContainsKey(MST[i])) // if this edge will be cutt { /*add it to adjecency list*/ if (!adj_lst.ContainsKey(MST[i].from)) { adj_lst.Add(MST[i].from, new List <int>()); } if (!adj_lst.ContainsKey(MST[i].to)) { adj_lst.Add(MST[i].to, new List <int>()); } } else // if this edge will not be cutt { /*add it to adjecency list*/ if (!adj_lst.ContainsKey(MST[i].from)) { adj_lst.Add(MST[i].from, new List <int> { MST[i].to }); } else { adj_lst[MST[i].from].Add(MST[i].to); } if (!adj_lst.ContainsKey(MST[i].to)) { adj_lst.Add(MST[i].to, new List <int> { MST[i].from }); } else { adj_lst[MST[i].to].Add(MST[i].from); } } } int sz = H.Count; while (sz > 0) // move in the number of cutted edges { GRAPH R = H.Dequeue(); // dequeue the first edge with complexty O(log K) sz--; Number_Nodes = 0; if (!vis[R.from]) // if the from is not visited { Number_Nodes = 0; Rd = G = B = 0; dfs(R.from); Rd /= Number_Nodes; G /= Number_Nodes; B /= Number_Nodes; Val.red = (byte)Rd; Val.green = (byte)G; Val.blue = (byte)B; /*shift the accumilated red green blue from this cluster*/ int ind1 = Val.red << 8 | Val.green; int ind = ind1 << 8 | Val.blue; nodes[Cluster_Number] = ind;// reuse the nodes to add the average of this cluster Cluster_Number++; } if (!vis[R.to])// if the from is not visited { Number_Nodes = 0; Rd = G = B = 0; dfs(R.to); Rd /= Number_Nodes; G /= Number_Nodes; B /= Number_Nodes; Val.red = (byte)Rd; Val.green = (byte)G; Val.blue = (byte)B; /*shift the accumilated red green blue from this cluster*/ int ind1 = Val.red << 8 | Val.green; int ind = ind1 << 8 | Val.blue; nodes[Cluster_Number] = ind;// reuse the nodes to add the average of this cluster Cluster_Number++; } } }//Clustring
} //get_distincit public static void grph(int CLUS)// graph construction and getting edges that will be cut that take number of clusters { /* * Total complexty = O (E log (k)) * --where E is the number of edges and K is the number of clusters wanted to cut */ float min = 10000000, newedge; //min is minimum value that take from moving from exesting node to another node, newedge is edge between exesting node to another node int k = 0, count = nodes.Count; //k is the index of minimum node that i would start in next time bool[] vstd = new bool[16777216]; //to check if node has been visited before (get values between it and all another none visited nodes) VX = new Dictionary <GRAPH, float>(); // initialize th helper of periority_queue H = new FastPriorityQueue <GRAPH>(CLUS - 1); //initialize periority_queue for (int i = k; ;) //first loop to move in distincit node { bool ch = false; // if it still false then i can't go anywhere because all nodes have been visited if (vstd[nodes[i]]) { continue; // if the node that i stand in is visited then continue } vstd[nodes[i]] = true; //this not is not visited before then make it as visited min = 10000000; // give minimum every time very large value for (int j = 0; j < count; j++) //second loop to move in distincit node { if (vstd[nodes[j]]) { continue; //if the node that i stand in is visited then continue } ch = true; //then it i found another node to move in byte[] b = BitConverter.GetBytes(nodes[i]), bb = BitConverter.GetBytes(nodes[j]); // convert the shifted integer to red and green and blue newedge = (((b[0] - bb[0]) * (b[0] - bb[0])) + ((b[1] - bb[1]) * (b[1] - bb[1])) + ((b[2] - bb[2]) * (b[2] - bb[2]))); //calculate the edge between to nodes if (newedge < min) //if the edge i have less than minimum then { min = newedge; //make the minimum is newedge k = j; //and save its index to start from it the next time } if (MST[j].edge < min) // if the edge that is already saved is less than minimum then { min = MST[j].edge; //make the minimum is saved edge k = j; //and save its index to start from it the next time } if (newedge < (float)MST[j].edge) // if the calculated edge before is larger than the newly calculated edge then { MST[j].edge = newedge; //then replace the calculaed edge with the new minimum edge MST[j].from = nodes[i]; //and change from where it comes } } i = k; //K is the minimum index that i will start the loop with if (ch == false) // then i cant go to any node again because all nodes have been visited then choose the cutted edges { GRAPH T = new GRAPH(); //temp to delete the deleted edge from dictionary as it is deleted from periority_queue for (int y = 1; y < MST.Count; y++) //move in all Minimum spanning tree { if (H.Count < CLUS - 1) // if the periority_queue is not filled with required number of clusters then { H.Enqueue(MST[y], MST[y].edge); // add in periority_queue with complexty O(log K) k is the wanted number of clusters VX.Add(MST[y], MST[y].edge); // add in the dictionary this edge } else//if the periority_queue is filled with required number of clusters then { if (H.First.edge < MST[y].edge) //check if the edge that i stand is larger than the top of queue that contain the smallest edge { T = H.Dequeue(); //pop the smallest from the queue VX.Remove(T); //remove also this node from dictionary H.Enqueue(MST[y], MST[y].edge); //enqueue the new large node with the new large edge with complexty O(log K) VX.Add(MST[y], MST[y].edge); //add the new large node with the new large edge } } } } if (!ch) { break; //if i can't go anywhere then break } }//main loop /* this to get cost of minimum spanning tree*/ /* double sum = 0; * for (int i = 1; i < MST.Count; i++) * { * sum += Math.Sqrt(MST[i].edge); * } * MessageBox.Show(sum.ToString());*/ }