using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PR_IA2_2010_Clases
{
static public class Algoritmos
{
///
/// Algoritmo para el cálculo de la distancia Euclidea entre los
/// objetos a partir de los distintos atributos.
///
/// Lista de arrays de strings que representan
/// los atributos de los objetos
///
/// distancias euclideas entre los objetos
static public double[,] distanciaEuclidea(List
{
try
{
double[,] matriz = null;
//creamos la matriz de distancias en el intervalo [0,1]
//con la distancia media según el nº de atributos (6):
if (datos.Count>0)
{
matriz = new double[datos.Count, datos.Count];
for (int i = 0; i < datos.Count; i++)
{
for (int j= 0; j < datos.Count ; j++)
{
double suma = 0;
for (int k = 0; k < datos[i].Count() - 2; k++)
{
suma+=Math.Pow(double.Parse(datos[i][k])-double.Parse(datos[j][k]),2);
}
double result = Math.Sqrt(suma);
matriz[i, j] = 1-(result/6);
}
}
}
return matriz;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Algoritmo que calcula la matriz de semejanzas transitiva a partir
/// de una no transitiva.
///
/// Matriz de semejanzas no transitiva
///
static public double[,] clausuraTransitiva(double[,] S)
{
try
{
double[,] R;
do
{
R = (double[,])S.Clone();
S = composicion(R, (double[,])R.Clone());
}while (!iguales(S,R));
return S;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// composición de las semejanzas de una clausura transitiva
///
/// matriz de semejanzas
/// matriz de semejanzas
///
static private double[,] composicion(double[,] R1, double[,] R2)
{
try
{
double[,] S=new double[R1.GetLength(0),R1.GetLength(0)];
for (int x = 0; x < R1.GetLength(0); x++)
{
for (int y = 0; y < R1.GetLength(0); y++)
{
S[x,y] = 0;
for (int z = 0; z < R1.GetLength(0); z++)
{
S[x, y] = Math.Max(S[x,y], Math.Min(R1[x,z],R2[z,y]));
}
}
}
return S;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Determina si 2 matrices son iguales
///
///
///
///
static private bool iguales(Double[,] S, Double[,] R)
{
try
{
for (int i = 0; i < S.GetLength(0); i++)
{
for (int j = 0; j < S.GetLength(1); j++)
{
if (S[i, j] != R[i, j])
return false;
}
}
}
catch (Exception ex)
{
return false;
}
return true;
}
///
/// Crea un dendrograma a partir de una matriz de semejanzas
/// transitiva.
///
/// matriz de datos
///
static public string dendrograma(double[,] matriz)
{
try
{
string result="";
List
List
//añade los datos alfa de la matriz (resultados).
for (int i = 0; i < matriz.GetLength(0); i++)
{
for (int j = i; j < matriz.GetLength(1); j++)
{
if (!alfa.Contains(matriz[i,j]))
{
alfa.Add(matriz[i, j]);
}
}
}
//ordenamos los datos alfa para ver
//los objetos relacionados.
alfa.Sort();
//recorremos toda la matriz.
for (int x=alfa.Count-1;x>=0;x--)
{
for (int i = 0; i < matriz.GetLength(0); i++)
{
for (int j = i+1; j < matriz.GetLength(1); j++)
{
//Si coincide el valor de la semejanza con
//el valor alfa que estamos tratando,
//añadimos la relación a la cadena final.
if (alfa[x] == matriz[i, j])
{
string strI = "x"+ (i+1).ToString()+" ";
string strJ = "x"+ (j+1).ToString()+" ";
bool existeI = result.Contains(strI);
bool existeJ = result.Contains(strJ);
//sólo añadimos el emparejamiento si
//no existe una relación de emparejamiento
//anterior directa o derivada de otra relación
//de emparejamiento
if (!emparejamientos.Contains(strI + "," + strJ) &&
!emparejamientos.Contains(strJ+","+strI))
{
//se trabaja con 4 supuestos a continuación
//al tratar la relación entre 2 objetos:
if (!existeI && existeJ)
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos, result, strJ)));
if (result.IndexOf("{" + strJ) > -1)
{
result = result.Replace("{" + strJ, "{{" + strJ);
result += "," + strI + "}";
}
if (result.IndexOf(strJ + "}") > -1)
{
result = result.Insert(buscarLLaveAbrir(emparejamientos,result, strI), "{");
result += "," + strI + "}";
}
}
if (existeI && !existeJ)
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strJ, strI,
result.Substring(buscarLLaveAbrir(emparejamientos,result, strI)));
result = result.Insert(buscarLLaveAbrir(emparejamientos,result, strI), "{");
result += "," + strJ + "}";
}
if (existeI && existeJ)
{
if (result.IndexOf(strI) > result.IndexOf(strJ))
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos, result, strJ)));
result = result.Insert(buscarLLaveAbrir(emparejamientos, result, strJ), "{");
result = result.Insert(buscarLLaveCerrar(emparejamientos, result, strJ), "}");
result = result.Insert(buscarLLaveAbriryCierreParaComa(emparejamientos, result, strJ) + 1, ",");
}
else
{
emparejamientos = anyadirEmparejamientos(emparejamientos, strI, strJ,
result.Substring(buscarLLaveAbrir(emparejamientos,result, strI)));
result = result.Insert(buscarLLaveAbrir(emparejamientos, result, strI), "{");
result = result.Insert(buscarLLaveCerrar(emparejamientos, result, strI), "}");
result = result.Insert(buscarLLaveAbriryCierreParaComa(emparejamientos, result, strI) + 1, ",");
}
}
if (!existeI && !existeJ)
{
emparejamientos.Add(strI + "," + strJ);
result += ("{" + strI + "," + strJ + "}");
}
}
}
}
}
}
return result.Replace(" ","");
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return "";
}
///
/// Crea una lista de emparejamientos para no duplicar
/// los emparejamientos en el dendrograma final.
///
/// Lista de emparejamientos
/// nuevo objeto
/// objeto existente
/// cadena que engloba los objetos que se emparejan
/// con todos los objetos que se relacionan con ellos
///
static private List
string trozo)
{
try
{
char[] caracteresDelimitadores = { '{','}',',' };
string[] filas;
filas = trozo.Split(caracteresDelimitadores, StringSplitOptions.RemoveEmptyEntries);
//mediante una array añado todos los objetos relacionados
//a lista de emparejamientos.
for (int i = 0; i < filas.Count(); i++)
{
if (!emparejamientos.Contains(nuevo+','+filas[i])
&& nuevo!=filas[i])
{
emparejamientos.Add(nuevo + ',' + filas[i]);
}
for (int j = 0; j < filas.Count(); j++)
{
if (!emparejamientos.Contains(filas[i] + ',' + filas[j])
&& !emparejamientos.Contains(filas[j] + ',' + filas[i]) &&
filas[i]!=filas[j])
{
emparejamientos.Add(filas[i] + ',' + filas[j]);
}
}
}
return emparejamientos;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return null;
}
///
/// Busca la llave de abrir para hacer un emparejamiento
///
/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
///
/// emparejamiento
static private int buscarLLaveAbrir(List
{
try
{
int min = result.Length;
var lista= from e in emparejamientos
where e.IndexOf(I)>-1
select e;
//dentro de todos los emparejamientos de un objeto, obten-
//dremos el que esté en el lado más izquierdo del dendrograma
foreach (string str in lista)
{
if (result.IndexOf(str.Substring(0, str.IndexOf(","))) < min &&
result.IndexOf(str.Substring(0, str.IndexOf(","))) > -1)
min = result.IndexOf(str.Substring(0, str.IndexOf(",")));
if (result.IndexOf(str.Substring(str.IndexOf(","))) < min &&
result.IndexOf(str.Substring(str.IndexOf(","))) > -1)
min = result.IndexOf(str.Substring(str.IndexOf(","))) - str.Substring(0, str.IndexOf(",")).Length;
}
return min;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
///
/// Busca la llave de cerrar para hacer un emparejamiento
///
/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
///
/// emparejamiento
static private int buscarLLaveCerrar(List
{
try
{
int max =0;
var lista = from e in emparejamientos
where e.IndexOf(I) > -1
select e;
//dentro de todos los emparejamientos de un objeto, obten-
//dremos el que esté en el lado más derecho del dendrograma
foreach (string str in lista)
{
if (result.IndexOf(str.Substring(0,str.IndexOf(","))) > max)
max = result.IndexOf(str.Substring(0, str.IndexOf(","))) + str.Substring(0, str.IndexOf(",")).Length;
if (result.IndexOf(str.Substring(str.IndexOf(",")+1)) > max)
max = result.IndexOf(str.Substring(str.IndexOf(",") + 1)) + str.Substring(0, str.IndexOf(",")).Length;
}
return max;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
///
/// Dentro de cada emparejamiento, busca la posición intermedia de la
/// relación para insertar la coma de separación que deja el dendrograma
/// más claro de entender.
///
/// Lista de emparejamientos
/// dendrograma final
/// Objeto a buscar
///
static private int buscarLLaveAbriryCierreParaComa(List
{
try
{
int min = buscarLLaveAbrir(emparejamientos,result,I);
int numLlaveAbrir=1;
for (int i = min; i >= 0; i--)
{
if (result.Substring(i, 1) == "{")
numLlaveAbrir++;
else
break;
}
for (int i = min; i < result.Length; i++)
{
if (result.Substring(i, 1) == "}")
numLlaveAbrir--;
if (numLlaveAbrir == 0)
return i;
}
return min;
}
catch (Exception ex)
{
new Exception(ex.Message);
}
return 0;
}
}
}
No hay comentarios:
Publicar un comentario