Beispiel #1
0
        //Dado un elemento y una lista de clusters devuelve la posicion del cluster mas similar
        private int ClusterProcessedElement(Element e, List <Cluster> l)
        {
            //Esto es asi ya que estamos tratando con dissimilitud, es decir mientras mas pequeno mas cerca estan
            double minDist     = double.MaxValue;
            int    bestCluster = 0;

            for (int i = 0; i < ClustersCount; i++)
            {
                double dist = Proximity.CalculateProximity(e, l[i].Centroid);
                if (dist < minDist)
                {
                    minDist     = dist;
                    bestCluster = i;
                }
            }
            return(bestCluster);
        }
        private string BuildInputFile(ref int acurrent)
        {
            string folderpath = Utils.ExesFolderPath;
            string filename   = "inputgraph" + Utils.GetUniqueID + ".config";
            string filepath   = folderpath + Path.DirectorySeparatorChar + filename;

            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            FileStream   fs = new FileStream(filepath, FileMode.CreateNew, FileAccess.ReadWrite);
            StreamWriter sw = new StreamWriter(fs);

            //First Line #vertex , #edges , #code
            int vertices = Set.ElementsCount;
            int edges    = (vertices * (vertices - 1)) / 2;
            int code     = 1;

            string firstLine = vertices + " " + edges + " " + code;

            sw.WriteLine(firstLine);

            int edgesZero = 0;//Este es un numero par ya que si (i,j)=0 entonces tbn sera cero (j,i)=0

            //n-lines, where n is the amount of vertices, the vertices start in 1
            StringBuilder line;

            for (int i = 0; i < Set.ElementsCount; i++)
            {
                line = new StringBuilder();
                for (int j = 0; j < Set.ElementsCount; j++)
                {
                    if (i != j)
                    {
                        int    adj        = j + 1;
                        double edgeweight = Proximity.CalculateProximity(Set[i], Set[j]);

                        //Codigo Chiki
                        string   number = (edgeweight * 100000).ToString();
                        string[] parts  = number.Split('.');

                        int temp = 0;
                        if (!int.TryParse(parts[0], out temp))
                        {
                            temp = int.MaxValue;
                        }
                        //hasta aqui

                        if (temp != 0)
                        {
                            line.Append(adj + " " + temp + " ");
                        }
                        else
                        {
                            edgesZero++;
                        }
                    }
                }
                //Write the line for the vertex i+1
                sw.WriteLine(line);
            }

            sw.Flush();

            //Actualizar la cantidad de aristas ya que pudo haber aristas con costo cero
            //las cuales no pertenecen al grafo ya que segun la especificacion del fichero de entrada
            //el costo de las aristas debe ser mayor estricto que cero
            if (edgesZero > 0)
            {
                fs.Seek(0, SeekOrigin.Begin);
                string newFirstLine       = vertices + " " + (edges - edgesZero / 2) + " " + code;
                int    lengthNewFirstLine = newFirstLine.Length;
                int    lengthOldFirstLine = firstLine.Length;
                byte[] arr = new byte[lengthOldFirstLine];
                for (int i = 0; i < lengthNewFirstLine; i++)
                {
                    arr[i] = (byte)newFirstLine[i];
                }
                if (lengthNewFirstLine < lengthOldFirstLine)
                {
                    byte white = (byte)' ';
                    for (int i = lengthNewFirstLine; i < lengthOldFirstLine; i++)
                    {
                        arr[i] = white;
                    }
                }
                fs.Write(arr, 0, lengthOldFirstLine);
                fs.Flush();
            }
            sw.Close();
            fs.Close();

            return(filename);
        }
Beispiel #3
0
        public override Structuring BuildStructuring()
        {
            try
            {
                if (Set == null)
                {
                    throw new NullReferenceException();
                }

                int _current = 1;
                int _max     = Set.ElementsCount;
                if (IContainerProgressBar != null)
                {
                    IContainerProgressBar.ResetProgressBar(1, _max, true);
                    IContainerProgressBar.UpdateProgressBar(1, "Running Hierarchical agglomerative algorithm...", true);
                }

                if (ClustersCount > Set.ElementsCount)
                {
                    ClustersCount = Set.ElementsCount;
                }

                if (ClustersCount <= 0)
                {
                    throw new Exception("La cantidad de clusters debe ser mayor que cero");
                }
                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++)
                    {
                        if (IContainerProgressBar != null)
                        {
                            IContainerProgressBar.UpdateProgressBar(_current++, "Running Hierarchical agglomerative algorithm...", false);
                        }

                        temp.Add(Set[i]);
                    }

                    dic_clus.Add(name, new Cluster(name)
                    {
                        Elements = temp
                    });

                    Structuring = new Partition()
                    {
                        Clusters = dic_clus, Proximity = Proximity
                    };

                    if (IContainerProgressBar != null)
                    {
                        IContainerProgressBar.FinishProgressBar();
                    }

                    return(Structuring);
                }

                double AlfaI = 0, AlfaJ = 0, Beta = 0, Gamma = 0;

                //Al inicio cada elemento es un cluster
                double[,] DMatrix = new double[Set.Elements.Count, Set.Elements.Count];
                List <Cluster> clusters = new List <Cluster>();
                bool[]         des      = new bool[Set.Elements.Count];//true si ese elemento ya no es representativo

                for (int i = 0; i < Set.Elements.Count; i++)
                {
                    List <Element> l = new List <Element>();
                    l.Add(Set[i]);
                    clusters.Add(new Cluster("C-" + i, l));
                }

                //Construir para cada cluster una cola con prioridad
                //con las disimilitudes de el con el resto de los clusters
                //y la matriz de todas las disimilitudes O(n2*log n)

                List <HeapArray <Container> > lh = new List <HeapArray <Container> >();

                for (int i = 0; i < Set.Elements.Count; i++)
                {
                    lh.Add(new HeapArray <Container>(Set.Elements.Count - 1));//No se pone la diss de un elemento con el mismo
                }
                for (int i = 0; i < Set.Elements.Count; i++)
                {
                    for (int j = i + 1; j < Set.Elements.Count; j++)
                    {
                        double temp_diss = Proximity.CalculateProximity(Set.Elements[i], Set.Elements[j]);

                        DMatrix[i, j] = temp_diss;
                        DMatrix[j, i] = temp_diss;
                        lh[i].Add(new Container {
                            Rank = temp_diss, Name = i, Cluster = j
                        });
                        lh[j].Add(new Container {
                            Rank = temp_diss, Name = j, Cluster = i
                        });
                    }
                }

                //Algoritmo O(n2*log n)
                for (int i = Set.Elements.Count; i > ClustersCount; i--)
                {
                    if (IContainerProgressBar != null)
                    {
                        IContainerProgressBar.UpdateProgressBar(_current++, "Running Hierarchical agglomerative algorithm...", false);
                    }

                    //Seleccionar los 2 clusters mas similares O(n)
                    double min = double.MaxValue;
                    int    cluster_i = 0, cluster_j = 0;
                    int    pos_cluster_i = 0, pos_cluster_j = 0;

                    for (int j = lh.Count - 1; j >= 0; j--)
                    {
                        if (lh[j].First.Rank < min)
                        {
                            min           = lh[j].First.Rank;
                            cluster_i     = lh[j].First.Name;
                            cluster_j     = lh[j].First.Cluster;
                            pos_cluster_i = j;
                        }
                    }
                    for (int j = 0; j < lh.Count; j++)
                    {
                        if (lh[j].First != null && lh[j].First.Name == cluster_j)
                        {
                            pos_cluster_j = j;
                            break;
                        }
                    }

                    //Calcular posiciones para borrar y guardar

                    int erase_pos = 0, final_pos = 0;

                    erase_pos = pos_cluster_i > pos_cluster_j ? pos_cluster_i : pos_cluster_j;
                    final_pos = pos_cluster_i < pos_cluster_j ? pos_cluster_i : pos_cluster_j;

                    lh.RemoveAt(erase_pos);

                    //Actualizar los parametros AlfaI, AlfaJ, Beta y Gamma
                    double cluster_i_count = clusters[erase_pos].ElementsCount;
                    double cluster_j_count = clusters[final_pos].ElementsCount;

                    AlfaI = UpdateAlfaI(cluster_i_count, cluster_j_count);
                    AlfaJ = UpdateAlfaJ(cluster_i_count, cluster_j_count);
                    Beta  = UpdateBeta(cluster_i_count, cluster_j_count);
                    Gamma = UpdateGamma(cluster_i_count, cluster_j_count);

                    //Unir los clusters

                    foreach (Element item in clusters[erase_pos].Elements)
                    {
                        clusters[final_pos].AddElement(item);
                    }
                    clusters.RemoveAt(erase_pos);

                    //Actualizar DMatrix con la disimilitud del nuevo cluster
                    //y el resto de los clusters O(n)
                    //Formula que se usa segun el algoritmo

                    //La posicion del cluster i en Dmatrix es cluster_i
                    //La posicion del cluster j en Dmatrix es cluster_j

                    int pos_h = -1;
                    int pos_i = cluster_i;
                    int pos_j = cluster_j;

                    if (erase_pos == pos_cluster_i)
                    {
                        des[cluster_i] = true;
                        pos_h          = cluster_j;
                    }
                    else
                    {
                        des[cluster_j] = true;
                        pos_h          = cluster_i;
                    }

                    for (int k = 0; k < DMatrix.GetLength(0); k++)
                    {
                        DMatrix[pos_h, k] = AlfaI * DMatrix[pos_i, k] + AlfaJ * DMatrix[pos_j, k] + Beta * DMatrix[pos_i, pos_j] + Gamma * Math.Abs(DMatrix[pos_i, k] - DMatrix[pos_j, k]);
                        DMatrix[k, pos_h] = DMatrix[pos_h, k];
                    }

                    //Actualizar array de Heaps con la disimilitud del nuevo cluster
                    //y el resto de los clusters O(n*log n)

                    lh[final_pos] = new HeapArray <Container>(Set.Elements.Count - 1);

                    for (int j = 0; j < lh.Count; j++)
                    {
                        Container[] lc = lh[j].ToArray;
                        lh[j] = new HeapArray <Container>(Set.Elements.Count - 1);
                        for (int k = 1; k < lc.Length; k++)
                        {
                            if (lc[k] == null)
                            {
                                break;
                            }
                            if (lc[k].Cluster != cluster_i && lc[k].Cluster != cluster_j)
                            {
                                lh[j].Add(lc[k]);
                            }
                        }
                        if (j != final_pos && lh[j].First != null)
                        {
                            lh[j].Add(new Container {
                                Rank = DMatrix[pos_h, lh[j].First.Name], Name = lh[j].First.Name, Cluster = pos_h
                            });
                        }
                    }

                    for (int j = 0; j < DMatrix.GetLength(0); j++)
                    {
                        if (pos_h != j && pos_j != j && pos_i != j && !des[j])
                        {
                            lh[final_pos].Add(new Container {
                                Rank = DMatrix[pos_h, j], Name = pos_h, Cluster = j
                            });
                        }
                    }
                }

                //Crear Dictionary<string,Cluster> para construir la particion
                Dictionary <string, Cluster> dic_clusters = new Dictionary <string, Cluster>();
                int cont = 0;
                for (int i = 0; i < clusters.Count; i++)
                {
                    if (clusters[i] != null)
                    {
                        clusters[i].Name = "C-" + cont;
                        dic_clusters.Add(clusters[i].Name, clusters[i]);
                        cont++;
                    }
                }

                Structuring = new Partition()
                {
                    Clusters = dic_clusters, Proximity = Proximity
                };

                if (IContainerProgressBar != null)
                {
                    IContainerProgressBar.FinishProgressBar();
                }

                return(Structuring);
            }
            catch
            {
                if (IContainerProgressBar != null)
                {
                    IContainerProgressBar.ShowError("Error occurred in Hierarchical agglomerative algorithm.");
                }
                return(null);
            }
        }