Beispiel #1
0
        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;
        }