/// <summary> /// Calcul de la distance entre 2 classes /// </summary> /// <param name="classe1">Classe 1</param> /// <param name="classe2">Classe 2</param> /// <returns>Distance entre les classes 1 et 2</returns> private double CalculerDistanceClasses(Classe classe1, Classe classe2) { double distanceMin = 1000; // On calcule la distance entre chaque neurone de chaque classe foreach (Neurone neurone1 in classe1.ListeNeurones) { foreach (Neurone neurone2 in classe2.ListeNeurones) { if (neurone1.CalculerDistance(neurone2) < distanceMin) { distanceMin = neurone1.CalculerDistance(neurone2); } } } // On renvoie la distance la plus courte return(distanceMin); }
public List <Classe> Regroupement(List <Observation> observations, int nbClasses) { // Recherche des neurones qui ne gagnent jamais ou presque jamais // Pour cela, on compte le nombre de fois où le neurone à l’erreur minimale List <Classe> classes = new List <Classe>(); // Tableau pour compter int[,] comptage = new int[nbLignes, nbColonnes]; // Initialisation à 0 pour tous les neurones de la carte for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { comptage[i, j] = 0; } } // Pour chaque observation, on cherche quel neurone à l’erreur la plus faible foreach (Observation observation in observations) { double erreurMin = 100000; int ligneMieux = 0; int colonneMieux = 0; for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { if (carte[i, j].CalculerErreur(observation) < erreurMin) { ligneMieux = i; colonneMieux = j; erreurMin = carte[i, j].CalculerErreur(observation); } } } comptage[ligneMieux, colonneMieux]++; } // Initialisation des classes (en prenant les meilleures) for (int i = 0; i < nbLignes; i++) { for (int j = 0; j < nbColonnes; j++) { if (comptage[i, j] > 10) { classes.Add(new Classe(carte[i, j])); } } } // Fusion des classes : le critère le plus simple est la distance interclasse do { Classe classeFusionnee1 = classes[0]; Classe classeFusionnee2 = classes[1]; double distanceMin = 1000000; foreach (Classe classe1 in classes) { foreach (Classe classe2 in classes) { if (classe1 != classe2) { if (CalculerDistanceClasses(classe1, classe2) < distanceMin) { distanceMin = CalculerDistanceClasses(classe1, classe2); classeFusionnee1 = classe1; classeFusionnee2 = classe2; } } } } // Fusion des 2 classes les plus proches classeFusionnee1.FusionnerAvec(classeFusionnee2); classes.Remove(classeFusionnee2); }while (classes.Count > nbClasses); return(classes); }