private void buttonCourtChemin_Click(object sender, EventArgs e) { NodeRecherche.nomLieuFinal = textBox_noeudFinal.Text; Graph graph = new Graph(); NodeRecherche noeudInit = new NodeRecherche(textBox_noeudInit.Text); List<GenericNode> chemin = graph.RechercheSolutionAEtoile(noeudInit); double cout=0; NodeRecherche n1 = noeudInit; NodeRecherche n2; listBoxChemin.Items.Clear(); foreach (GenericNode n in chemin) { listBoxChemin.Items.Add(n.ToString()); n2 = n as NodeRecherche; if (n2!=n1) cout += n1.GetArcCost(n2); n1 = n2; } textBoxCout.Text = cout.ToString(); graph.GetSearchTree(treeView1); }
//crée un NodeRecherche pour chaque voisin du noeud dans le reseau public override List<GenericNode> GetListSucc() { List<GenericNode> ListeSucc = new List<GenericNode>(); RouteNode referent = reseau.GetNodes()[(Name[0]) - 65]; //pour chaque voisin de ce noeud dans le reseau foreach (KeyValuePair<RouteNode,int> voisin in referent.GetVoisins()) { //crée un noeud du meme nom NodeRecherche successeur = new NodeRecherche(voisin.Key.GetName()); //et l'ajoute à la liste ListeSucc.Add(successeur); } return ListeSucc; }
//renvoie le cout du + court chemin de noeudInital à noeudFinal public double calculeMeilleurCout(string noeudInital, string noeudFinal, out List<GenericNode> chemin) { NodeRecherche noeudInit = new NodeRecherche(noeudInital); // départ de noeudInital NodeRecherche.nomLieuFinal = noeudFinal; // retour à noeudFinal Graph graph = new Graph(); //meilleur chemin de noeudInital à noeudFinal chemin = graph.RechercheSolutionAEtoile(noeudInit); double cout = 0; NodeRecherche n1 = noeudInit; NodeRecherche n2; //somme des couts intermédiaires foreach (GenericNode n in chemin) { n2 = n as NodeRecherche; if (n2 != n1) cout += n1.GetArcCost(n2); n1 = n2; } return (cout); }
// renvoie le chemin le plus court de A à A en passant par les points de passage séléctionnés public double getItineraire(List<string> pointsPassage, out string cheminString) { pointsPassage.Add("A"); List<string> pointsPassageOrdonnes = new List<string>(); //liste ordonnée des noeuds du meilleur chemin List<NodeRecherche> cheminTotal = new List<NodeRecherche>(); // cout associé double coutTotal = 0; // dico~matrice des <chemins+couts> de chaq couple de points de passage Dictionary<List<GenericNode>, double> coutsInter = new Dictionary<List<GenericNode>, double>(); //remplissage du dico ~matrice //pour chaque couple de noeuds foreach (string np1 in pointsPassage) { foreach (string np2 in pointsPassage) { if (np1 != np2) // diagonale de la matrice nulle { List<GenericNode> chemin = new List<GenericNode>(); double cout = calculeMeilleurCout(np1, np2, out chemin); coutsInter.Add(chemin, cout); } } } List <string> coutsInterString = new List<string>(); foreach(List<GenericNode> lgn in coutsInter.Keys) { coutsInterString.Add(string.Join(", ", lgn)); } Console.WriteLine("chemins inter : "+ string.Join("| ",coutsInterString)); Console.WriteLine("couts associés : " + string.Join(" | ", coutsInter.Values)); // a partir de cette "matrice", calcul des distances de proche en proche // pour définir le chemin total à parcourir dans l'ordre optimal // => pr chaq "ligne" de la matrice = pr chaque couple contenant le noeud init // on va au prochain plus proche (n2) //on stocke le nom du noeud et le cout associé // on passe sur la "ligne" de n2 et on va au plus proche... etc // a la fin, on a la liste des noeuds du chemin optimal, et le cout total GenericNode noeudCourant = new NodeRecherche("A"); // on demarre en A GenericNode prochainNoeud; pointsPassageOrdonnes.Add(noeudCourant.GetNom()); // tant qu'on n'a pas tout visité et qu'on n'est pas retourné en A while (!(tousVisites(pointsPassage, pointsPassageOrdonnes) && noeudCourant.GetNom() == "A")) { //dico temporaire correspondant aux successeurs du noeudCourant (= sa ligne dans la matrice) Dictionary<List<GenericNode>, double> successeurs = new Dictionary<List<GenericNode>, double>(); foreach (KeyValuePair<List<GenericNode>, double> couple in coutsInter) { if (couple.Key.First().GetNom() == noeudCourant.GetNom() && //chemin au départ de noeudCourant (!pointsPassageOrdonnes.Contains(couple.Key.Last().GetNom()) || // evite doublons //sauf pour retour en A à la fin couple.Key.Last().GetNom()=="A" && tousVisites(pointsPassage, pointsPassageOrdonnes))) { successeurs.Add(couple.Key, couple.Value); } } Console.WriteLine("le noeud {0} a {1} successeur(s)", noeudCourant.GetNom(), successeurs.Count().ToString()); //recherche du successeur le plus proche foreach (KeyValuePair<List<GenericNode>, double> succ in successeurs) { // celui dont le chemin est le plus court if (succ.Value == successeurs.Values.Min()) { // dernière valeur du chemin pour aller à ce noeud prochainNoeud = succ.Key.Last(); //ajout du noeud a la liste ordonnée pointsPassageOrdonnes.Add(prochainNoeud.GetNom()); //ajout du cout du trajet intermédiaire coutTotal += succ.Value; //ajout de chaque point intermédiaire au chemin total foreach (NodeRecherche n in succ.Key) { if(cheminTotal.Count==0 || n.GetNom()!=cheminTotal.Last().GetNom()) cheminTotal.Add(n); } //passage au couple suivant, c à d au depart de ce noeud noeudCourant = prochainNoeud; // si plusieurs noeuds ont le même cout minimal, on s'arrete au premier break; } } } // conversion du chemin en string lisible cheminString = ""; cheminString+= String.Join(", ", cheminTotal); return coutTotal; }