/// <summary> /// /// </summary> /// <param name="rawCouples">unclustered array of PredictionCouples having each a similarity assigned to it</param> /// <param name="clusterWidth"> the width of the cluster grouping this PredictionCouples ex: 0.1 </param> /// <returns></returns> public static List <Cluster> Cluster(IEnumerable <PredictionCouple> rawCouples, double clusterWidth) { /// TODO : optimize Function List <Cluster> finalList = new List <Cluster>(); double startingBound = 0; var sortedData = from item in rawCouples orderby item.Similarity descending select item; if (clusterWidth > 1) { clusterWidth = 1; } while (startingBound <= 1 - clusterWidth) { Cluster cluster = new Cluster(startingBound, startingBound + clusterWidth); ///TODO : optimize this piece of code to not traverse all sortedData everyTime foreach (PredictionCouple item in sortedData) { /// add element if he had similarity in this cluster cluster.AddElement(item); } finalList.Add(cluster); startingBound += clusterWidth; } return(finalList); }
public override Structuring TurnOffReduction(Set dataSet, Structuring partition) { if (partition is ReductionPartition) { return(((ReductionPartition)partition).Partition); } else { Dictionary <string, Cluster> _dic = new Dictionary <string, Cluster>(); foreach (var item in partition.Clusters) { Cluster _cluster = item.Value; Cluster _newCluster = new Cluster(_cluster.Name, new List <Element>()); foreach (var _e in _cluster.Elements) { foreach (var _object in _e.Values) { _newCluster.AddElement((Element)_object); } } _dic.Add(_newCluster.Name, _newCluster); } return(new Partition() { Clusters = _dic, Proximity = partition.Proximity }); } }
public override Structuring BuildStructuring() { if (Structurings == null || Set == null) { throw new NullReferenceException(); } if (IContainerProgressBar != null) { IContainerProgressBar.ResetProgressBar(1, 1, true); IContainerProgressBar.UpdateProgressBar(0, "Running QMI algorithm...", true); } List <Attribute> list_att = new List <Attribute>(); int cont = 0; foreach (Structuring s in Structurings) { foreach (Cluster c in s.Clusters.Values) { Attribute att = new Attribute("x" + cont, null); cont++; att.AttributeType = AttributeType.Numeric; list_att.Add(att); } } Set newset = new Set("Artificial"); newset.Attributes = new Attributes(list_att); newset.ElementType = ElementType.Numeric; foreach (Element e in Set.Elements) { List <object> values = new List <object>(); foreach (Structuring s in Structurings) { foreach (Cluster c in s.Clusters.Values) { double temp = c.HaveElement(e) ? 1 : 0; temp = temp - ((double)c.ElementsCount / (double)Set.ElementsCount); values.Add(temp); } } Element newelement = new Element(newset, values); newelement.Name = e.Name; newelement.Index = e.Index; newset.AddElement(newelement); } KMeans kms = new KMeans(newset, new EuclideanDistance() { AttributesToCalculateProximity = newset.Attributes.Values }); kms.ClustersCount = ClusterCount; kms.IterationsCount = IterationsCount; kms.Seed = Environment.TickCount; kms.IContainerProgressBar = IContainerProgressBar; Structuring art_struct = kms.BuildStructuring(); List <Cluster> clusters = new List <Cluster>(); cont = 0; foreach (Cluster c in art_struct.Clusters.Values) { Cluster temp = new Cluster("C-" + cont); cont++; foreach (Element item in c.Elements) { temp.AddElement(Set[item.Index]); } clusters.Add(temp); } Dictionary <string, Cluster> temp_dic = new Dictionary <string, Cluster>(); foreach (Cluster item in clusters) { temp_dic.Add(item.Name, item); } Structuring real_struct = new Partition() { Clusters = temp_dic }; return(real_struct); }
public override Structuring BuildStructuring() { try { if (Set == null || Structurings == null) { throw new NullReferenceException(); } int _current = 1, _max = IterationsCount; if (IContainerProgressBar != null) { IContainerProgressBar.ResetProgressBar(1, _max, true); IContainerProgressBar.UpdateProgressBar(0, "Running Simulated Annealing MeetJoinClusters algorithm...", true); } int random_pos = new Random(Environment.TickCount).Next(0, StructuringsCount); //EuclideanDistance _eu = new EuclideanDistance(); //_eu.AttributesToCalculateProximity = Set.Attributes.Values; //KMeans _kmeans = new KMeans(Set, _eu); //_kmeans.ClustersCount =3; //_kmeans.Seed = Environment.TickCount; //_kmeans.IterationsCount = 100; //Structuring initial = Structurings[random_pos]; BOK bok = new BOK(Set, Structurings) { GenericDistances = new MirkinDistance() }; Structuring initial = UseBOK ? bok.BuildStructuring() : Structurings[0]; string[] initial_sol = new string[Set.ElementsCount]; for (int i = 0; i < Set.ElementsCount; i++) { initial_sol[i] = initial.Elements[Set[i]][0]; } int _maxCluster = initial.ClustersCount; List <string[]> labels_List = new List <string[]>(); //Convertir todas las particiones a arreglo de string, donde en cada posicion //esta la etiqueta del cluster al que pertenece el elemento j for (int i = 0; i < Structurings.Count; i++) { string[] _temp = new string[Set.ElementsCount]; labels_List.Add(_temp); for (int j = 0; j < Set.ElementsCount; j++) { _temp[j] = Structurings[i].Elements[Set[j]][0]; } } string[] _result_labels = SA <string[]> .RunSAOMNewNeighbor(Set, initial_sol, labels_List, Temperature, .99, 50, 1.05, 10, .5, IterationsCount, IContainerProgressBar, _current, GenericDistances, ref _maxCluster); Dictionary <string, Cluster> dic_clusters = new Dictionary <string, Cluster>(); for (int i = 0; i < Set.ElementsCount; i++) { if (dic_clusters.ContainsKey(_result_labels[i])) { dic_clusters[_result_labels[i]].AddElement(Set[i]); } else { Cluster c = new Cluster(_result_labels[i]); c.AddElement(Set[i]); dic_clusters.Add(c.Name, c); } } if (IContainerProgressBar != null) { IContainerProgressBar.FinishProgressBar(); } Structuring = new Partition() { Clusters = dic_clusters }; return(Structuring); } catch { if (IContainerProgressBar != null) { IContainerProgressBar.ShowError("Error occurred in Simulated Annealing MeetJoinClusters algorithm."); } return(null); } }
public override Structuring BuildStructuring() { try { if (Set == null || Structurings == null) { throw new NullReferenceException(); } int _current = 1, _maxpb = Set.ElementsCount * Structurings.Count; if (IContainerProgressBar != null) { IContainerProgressBar.ResetProgressBar(1, _maxpb, true); IContainerProgressBar.UpdateProgressBar(1, "Running HGPA algorithm...", true); } if (ClustersCount <= 0) { throw new Exception("La cantidad de clusters debe ser mayor que cero"); } else if (ClustersCount == 1) { Dictionary <string, Cluster> dic_clus = new Dictionary <string, Cluster>(); string name = "C-0"; List <Element> temp = new List <Element>(); for (int i = 0; i < Set.ElementsCount; i++) { temp.Add(Set[i]); } dic_clus.Add(name, new Cluster(name) { Elements = temp }); Structuring = new Partition() { Clusters = dic_clus }; if (IContainerProgressBar != null) { IContainerProgressBar.FinishProgressBar(); } return(Structuring); } else { #region Algorithm //Construir un conjunto de elementos donde ahora cada elemento es un label, //o lo que es lo mismo una hyperedge. Este seria el meta-grafo Set hyperedgeSet = new Set("HyperEdge Set"); int dimH = 0; foreach (Structuring s in Structurings) { dimH += s.ClustersCount; } byte[,] metagraph = new byte[Set.ElementsCount, dimH]; //Ahora por cada label annadir un nuevo elemento al conjunto, recordar que cada label //seria cada hyperedges, lo que ahora cada hyperedges estaria representada por la clase Element //pero la lista de Values seria el vector binario o mejor dicho los elementos que pertenecen //a la hyperedges. //La matriz metagraph es la representacion en vectores binarios del conjunto hyperedges. // Ojo esto ya ///////Es mejor representar cada hyperedges de esta forma es decir con los elementos que pertenecen // no se hace ///////a dicha hyperedges ya que si se representa por el vector binario entonces necesitariamos mucha memoria. int index = 0; foreach (Structuring structuring in Structurings) { foreach (Cluster cluster in structuring.Clusters.Values) { Element element = new Element(); element.Index = index; element.Name = "hyperedge-" + index; foreach (Element temp in cluster.Elements) { metagraph[temp.Index, index] = 1; if (IContainerProgressBar != null) { IContainerProgressBar.UpdateProgressBar(_current++, "Running HGPA algorithm...", false); } } hyperedgeSet.AddElement(element); index++; } } if (IContainerProgressBar != null) { IContainerProgressBar.UpdateProgressBar(_maxpb, "Running HGPA algorithm...", true); } Similarity _sim = new BinaryJaccardMeasure(metagraph); ClusterAlgorithm ca = new Metis(hyperedgeSet, _sim); ca.ClustersCount = ClustersCount; ca.BuildStructuring(); Partition metaClusters = (Partition)ca.Structuring; //Asignar cada elemento original a su metacluster correspondiente //double[] va a tener dimension igual a la cantidad de elementos iniciales y en cada posicion va a estar un numero entre 0 y 1 List <double[]> _meta_hyperedges = new List <double[]>(); foreach (Cluster _c in metaClusters.Clusters.Values) { double[] _meta_hyperedge = new double[metagraph.GetLength(0)]; foreach (Element _e in _c.Elements) { //_e.Index es la columna de la matrix metgraph, que dicha columna representa a ese elemento for (int row = 0; row < metagraph.GetLength(0); row++) { _meta_hyperedge[row] += metagraph[row, _e.Index]; } } //LLevar cada posicion a un valor enre 0 y 1 for (int i = 0; i < _meta_hyperedge.Length; i++) { _meta_hyperedge[i] = _meta_hyperedge[i] / _c.ElementsCount; } _meta_hyperedges.Add(_meta_hyperedge); } //Construir la particion final Dictionary <string, Cluster> _dic_clusters = new Dictionary <string, Cluster>(); for (int i = 0; i < Set.ElementsCount; i++) { Element _e = Set[i]; double _max = -1; int _meta_hyperedge = -1; for (int j = 0; j < _meta_hyperedges.Count; j++) { if (_meta_hyperedges[j][_e.Index] > _max) { _max = _meta_hyperedges[j][_e.Index]; _meta_hyperedge = j; } } string _nameOfCluster = "C-" + _meta_hyperedge; if (_dic_clusters.ContainsKey(_nameOfCluster)) { _dic_clusters[_nameOfCluster].AddElement(_e); } else { Cluster c = new Cluster(_nameOfCluster); c.AddElement(_e); _dic_clusters.Add(_nameOfCluster, c); } } Structuring = new Partition() { Clusters = _dic_clusters }; if (IContainerProgressBar != null) { IContainerProgressBar.FinishProgressBar(); } return(Structuring); #endregion } } catch { if (IContainerProgressBar != null) { IContainerProgressBar.ShowError("Error occurred in MCLA algorithm."); } return(null); } }
//OJO Excepciones porque dice que no puede acceder al fichero porque esta siendo usado por otro proceso //tbn da Excepcion porque dice que no existe el fichero. //Parece que el metis se demora un poco creandolo, debe ser algo de eso, y lo crea pero despues parece que empieza //a escribir sobre el y entonces es que me da la otra excepcion de que esta siendo usado por otra persona, es que todo //ocurre muy rapido, NUNCA ME HA DADO EXCEPCION EN EL MODO DEBUG public static Structuring BuildStructuringFromOutputFile(string inputfilename, Set Set, int ClustersCount, Proximity Proximity) { try { string folderpath = Utils.ExesFolderPath; string filename = inputfilename + ".part." + ClustersCount; string filepath = folderpath + Path.DirectorySeparatorChar + filename; //Dar tiempo a que el algoritmo Metis cree el fichero while (!File.Exists(filepath)) { } FileStream fs = null; bool ok = false; //Dar tiempo a que el algoritmo Metis termine de escribir sobre el fichero de salida while (!ok) { try { fs = new FileStream(filepath, FileMode.Open, FileAccess.Read); ok = true; } catch { } } StreamReader sr = new StreamReader(fs); Dictionary<string, Cluster> dic_clusters; try { //Crear Dictionary<string,Cluster> para poder construir la particion dic_clusters = new Dictionary<string, Cluster>(); string line; int vertex = 0; while ((line = sr.ReadLine()) != null) { int cluster = int.Parse(line); string nameOfCluster = "C-" + cluster; if (dic_clusters.ContainsKey(nameOfCluster)) { dic_clusters[nameOfCluster].AddElement(Set[vertex]); } else { Cluster c = new Cluster(nameOfCluster); c.AddElement(Set[vertex]); dic_clusters.Add(nameOfCluster, c); } vertex++; } } catch (Exception ex) { throw new Exception("Formato incorrecto del fichero de salida del algoritmo METIS \r\nInformacion Adicional: " + ex.Message); } finally { sr.Close(); fs.Close(); //Eliminar el fichero de entrada File.Delete(ExesFolderPath + Path.DirectorySeparatorChar + inputfilename); //Eliminar el fichero de salida File.Delete(filepath); } //Los numeros de las particiones comienzan con cero hasta el numero de particiones menos uno[0,...,P-1] return new Partition() { Clusters = dic_clusters, Proximity = Proximity }; } catch { return null; } }
private void Crossover(Pair parents) { parents.P1 = Utils.Clone((Structuring)parents.P1); parents.P2 = Utils.Clone((Structuring)parents.P2); Cluster new_c1 = new Cluster(parents.C1.Name); Cluster new_c2 = new Cluster(parents.C2.Name); List <Element> un_el_p1 = new List <Element>(); List <Element> un_el_p2 = new List <Element>(); foreach (Element item in parents.C1.Elements) { if (parents.C2.HaveElement(item)) { new_c2.AddElement(item); } //else if (!parents.P2.Clusters.Values.ToList().Exists(c => c.HaveElement(item))) // new_c2.AddElement(item); //else //{ // //Si entra aki, el problema es que un elemento de C1, no pertenece a C2 (C2 es un de la P2), ni tampoco // //pertenece a algun otro cluster de P2, por lo tanto ese elemento no esta en la particion P2, y P2 y P1 // //son particiones de un mismo conjunto. Este caso solamente se debe dar cuando P2 tiene elementos no asignados // //y este elemento que estoy analizando puede estar no asignado, ahi en P2. // throw new Exception("no puede entrara aki, siginificaria que cada particion tiene conjuntos distintos."); // string c_temp = parents.P2.Elements[item][0]; // parents.P2.Clusters[c_temp].Elements.Remove(item); // parents.P2.Elements.Remove(item); // un_el_p2.Add(item); //} } foreach (Element item in parents.C2.Elements) { if (parents.C1.HaveElement(item)) { new_c1.AddElement(item); } //else if (!parents.P1.Clusters.Values.ToList().Exists(c => c.HaveElement(item))) // new_c1.AddElement(item); //else //{ // for (int i = 0; i < parents.P1.Clusters.Values.ToList().Count; i++) // { // Cluster _ccc = parents.P1.Clusters.Values.ToList()[i]; // for (int ii = 0; ii < _ccc.ElementsCount; ii++) // { // if (_ccc[ii].Index == item.Index) // { // } // } // } // //Si entra aki, el problema es que un elemento de C1, no pertenece a C2 (C2 es un de la P2), ni tampoco // //pertenece a algun otro cluster de P2, por lo tanto ese elemento no esta en la particion P2, y P2 y P1 // //son particiones de un mismo conjunto. Este caso solamente se debe dar cuando P2 tiene elementos no asignados // //y este elemento que estoy analizando puede estar no asignado, ahi en P2. // throw new Exception("no puede entrara aki, siginificaria que cada particion tiene conjuntos distintos."); // string c_temp = parents.P1.Elements[item][0]; // parents.P1.Clusters[c_temp].Elements.Remove(item); // parents.P1.Elements.Remove(item); // un_el_p1.Add(item); //} } foreach (var item in new_c1.Elements) { parents.P1.Elements[item] = new List <string>() { new_c1.Name }; } foreach (var item in new_c2.Elements) { parents.P2.Elements[item] = new List <string>() { new_c2.Name }; } parents.P1.Clusters[new_c1.Name] = new_c1; parents.P2.Clusters[new_c2.Name] = new_c2; if (parents.P1.UnassignedElements != null) { parents.P1.UnassignedElements.AddRange(un_el_p1); } else { parents.P1.UnassignedElements = un_el_p1; } if (parents.P2.UnassignedElements != null) { parents.P2.UnassignedElements.AddRange(un_el_p2); } else { parents.P2.UnassignedElements = un_el_p2; } }
private void Crossover(Pair parents) { parents.P1 = Utils.Clone((Structuring)parents.P1); parents.P2 = Utils.Clone((Structuring)parents.P2); Cluster new_c1 = new Cluster(parents.C1.Name); Cluster new_c2 = new Cluster(parents.C2.Name); List<Element> un_el_p1=new List<Element>(); List<Element> un_el_p2=new List<Element>(); foreach (Element item in parents.C1.Elements) { if (parents.C2.HaveElement(item)) new_c2.AddElement(item); //else if (!parents.P2.Clusters.Values.ToList().Exists(c => c.HaveElement(item))) // new_c2.AddElement(item); //else //{ // //Si entra aki, el problema es que un elemento de C1, no pertenece a C2 (C2 es un de la P2), ni tampoco // //pertenece a algun otro cluster de P2, por lo tanto ese elemento no esta en la particion P2, y P2 y P1 // //son particiones de un mismo conjunto. Este caso solamente se debe dar cuando P2 tiene elementos no asignados // //y este elemento que estoy analizando puede estar no asignado, ahi en P2. // throw new Exception("no puede entrara aki, siginificaria que cada particion tiene conjuntos distintos."); // string c_temp = parents.P2.Elements[item][0]; // parents.P2.Clusters[c_temp].Elements.Remove(item); // parents.P2.Elements.Remove(item); // un_el_p2.Add(item); //} } foreach (Element item in parents.C2.Elements) { if (parents.C1.HaveElement(item)) new_c1.AddElement(item); //else if (!parents.P1.Clusters.Values.ToList().Exists(c => c.HaveElement(item))) // new_c1.AddElement(item); //else //{ // for (int i = 0; i < parents.P1.Clusters.Values.ToList().Count; i++) // { // Cluster _ccc = parents.P1.Clusters.Values.ToList()[i]; // for (int ii = 0; ii < _ccc.ElementsCount; ii++) // { // if (_ccc[ii].Index == item.Index) // { // } // } // } // //Si entra aki, el problema es que un elemento de C1, no pertenece a C2 (C2 es un de la P2), ni tampoco // //pertenece a algun otro cluster de P2, por lo tanto ese elemento no esta en la particion P2, y P2 y P1 // //son particiones de un mismo conjunto. Este caso solamente se debe dar cuando P2 tiene elementos no asignados // //y este elemento que estoy analizando puede estar no asignado, ahi en P2. // throw new Exception("no puede entrara aki, siginificaria que cada particion tiene conjuntos distintos."); // string c_temp = parents.P1.Elements[item][0]; // parents.P1.Clusters[c_temp].Elements.Remove(item); // parents.P1.Elements.Remove(item); // un_el_p1.Add(item); //} } foreach (var item in new_c1.Elements) { parents.P1.Elements[item] = new List<string>() { new_c1.Name }; } foreach (var item in new_c2.Elements) { parents.P2.Elements[item] = new List<string>() { new_c2.Name }; } parents.P1.Clusters[new_c1.Name] = new_c1; parents.P2.Clusters[new_c2.Name] = new_c2; if (parents.P1.UnassignedElements != null) parents.P1.UnassignedElements.AddRange(un_el_p1); else parents.P1.UnassignedElements = un_el_p1; if (parents.P2.UnassignedElements != null) parents.P2.UnassignedElements.AddRange(un_el_p2); else parents.P2.UnassignedElements = un_el_p2; }
public override Structuring BuildStructuring() { if (Structurings == null || Set == null) throw new NullReferenceException(); if (IContainerProgressBar != null) { IContainerProgressBar.ResetProgressBar(1, 1, true); IContainerProgressBar.UpdateProgressBar(0, "Running QMI algorithm...", true); } List<Attribute> list_att = new List<Attribute>(); int cont = 0; foreach (Structuring s in Structurings) { foreach (Cluster c in s.Clusters.Values) { Attribute att = new Attribute("x" + cont, null); cont++; att.AttributeType = AttributeType.Numeric; list_att.Add(att); } } Set newset = new Set("Artificial"); newset.Attributes = new Attributes(list_att); newset.ElementType = ElementType.Numeric; foreach (Element e in Set.Elements) { List<object> values = new List<object>(); foreach (Structuring s in Structurings) { foreach (Cluster c in s.Clusters.Values) { double temp = c.HaveElement(e) ? 1 : 0; temp = temp - ((double)c.ElementsCount / (double)Set.ElementsCount); values.Add(temp); } } Element newelement = new Element(newset, values); newelement.Name = e.Name; newelement.Index = e.Index; newset.AddElement(newelement); } KMeans kms = new KMeans(newset, new EuclideanDistance() { AttributesToCalculateProximity = newset.Attributes.Values }); kms.ClustersCount = ClusterCount; kms.IterationsCount = IterationsCount; kms.Seed = Environment.TickCount; kms.IContainerProgressBar = IContainerProgressBar; Structuring art_struct = kms.BuildStructuring(); List<Cluster> clusters = new List<Cluster>(); cont = 0; foreach (Cluster c in art_struct.Clusters.Values) { Cluster temp = new Cluster("C-" + cont); cont++; foreach (Element item in c.Elements) { temp.AddElement(Set[item.Index]); } clusters.Add(temp); } Dictionary<string, Cluster> temp_dic=new Dictionary<string,Cluster>(); foreach (Cluster item in clusters) { temp_dic.Add(item.Name, item); } Structuring real_struct = new Partition() { Clusters = temp_dic }; return real_struct; }
public override List <Structuring> GetReduction(Set dataSet, List <Structuring> realPartitions, out Set anewSet) { if (dataSet == null || realPartitions == null) { throw new ArgumentNullException(); } // Calculamos la matriz de adyacencia bool[,] adjMatrix = new bool[dataSet.ElementsCount, dataSet.ElementsCount]; int[] visited = new int[dataSet.ElementsCount]; int ccCount = 0; for (int i = 0; i < dataSet.ElementsCount - 1; i++) { for (int j = i + 1; j < dataSet.ElementsCount; j++) { int jointCount = 0; int halfPartitions = (int)Math.Floor(realPartitions.Count / 2.0); foreach (var partition in realPartitions) { if (partition.BeSameCluster(dataSet[i], dataSet[j])) { jointCount++; } if (jointCount > halfPartitions) { adjMatrix[i, j] = adjMatrix[j, i] = true; break; } } } } for (int i = 0; i < dataSet.ElementsCount; i++) { if (visited[i] == 0) { ccCount++; DFS(i, adjMatrix, visited, ccCount); } } fragments = new Dictionary <string, List <object> >(); for (int i = 1; i <= ccCount; i++) { fragments.Add("OurFragment-" + i, new List <object>()); } for (int i = 0; i < dataSet.ElementsCount; i++) { fragments["OurFragment-" + visited[i]].Add(dataSet[i]); } // La transformación List <Element> _elements = new List <Element>(); Set _newSet = new Set(dataSet.RelationName + "(Reduction-Set)", _elements, dataSet.Attributes); foreach (var item in fragments) { Element _e = new Element(_newSet, item.Value); _e.Name = item.Key; _elements.Add(_e); } anewSet = _newSet; List <Structuring> partitions = new List <Structuring>(); //Build partitions //First Partition Dictionary <string, Cluster> dic_clusters = new Dictionary <string, Cluster>(); for (int i = 0; i < anewSet.ElementsCount; i++) { Cluster _c = new Cluster("C-" + i); _c.AddElement(anewSet[i]); dic_clusters.Add(_c.Name, _c); } partitions.Add(new Partition() { Clusters = dic_clusters }); //realPartitions.ForEach(rp => partitions.Add(new ReductionPartition(rp, _newSet, fragments))); return(partitions); }