/// <summary> /// faz o agrupamento dos dados de forma iterativa /// </summary> /// <param name="Centroides"></param> public void Agrupa(List <List <double> > Centroides) { //lista para armazenar as distancias var distancias = new List <double>(); /*percorro todos os registros da minha base de dados * e para cada registro calculo a distancia entre ele e os centroides */ foreach (DataRow row in Dados.Rows) { //separo um registro da minha base var reg = row.ItemArray.Select(x => Convert.ToDouble(x)).Take(numeroDeAtributos).ToList(); distancias.Clear(); /*adiciona a lista as distancia do registro para todos * os centroides */ foreach (List <double> centroide in Centroides) { //calcula a distancia entre o registro e o centroide distancias.Add( Formulas.Distancia(reg, centroide) ); } /*Procuro na lista de distancias qual a menor * e coloco ela como "DistanciaMin" do registro*/ row["DistanciaMin"] = distancias.Min(); //coloco o grupo desse registro como aquele que teve a menor distancia row["Grupo"] = distancias.IndexOf(distancias.Min()); } //guardo os valores de coesão e separação var CoesaoGeral = Coesoes.Sum(); var SeparacaoGeral = Separacoes.Sum(); //calculo a coesão e separações dos novos grupos gerados CalculoCoesao(); CalculoSeparacao(); Tela.Escrever("Iteração :" + NumeroIteracoes); Tela.Escrever("\nCentroides:"); Tela.Escrever(this.Centroides); Tela.Escrever("\nCoesão:"); Tela.Escrever(Coesoes.Sum()); Tela.Escrever("\nSeparação:"); Tela.Escrever(Separacoes.Sum()); RecalculaCentroides(); //Criterio de parada do algoritmo if ((CoesaoGeral == Coesoes.Sum()) && (SeparacaoGeral == Separacoes.Sum())) { return; } NumeroIteracoes++; Agrupa(this.Centroides); }
/// <summary> /// Calculo da Coesao /// soma da distancia de todos os itens do grupo para seu centroide /// </summary> public void CalculoCoesao() { Coesoes.Clear(); for (int i = 0; i <= Centroides.Count - 1; i++) { Coesoes.Add( Dados.AsEnumerable() .Where(x => x.Field <int>("Grupo") == i) .Sum(x => x.Field <double>("DistanciaMin")) ); } }