예제 #1
0
        /// <summary>
        /// Permet de trouver les successeurs du dernier nœud fermé
        /// </summary>
        /// <param name="N">Nœud dont on cherche les successeurs</param>
        private void MettreAJourSuccesseurs(Noeud N)
        {
            // On fait appel à GetListSucc, méthode abstraite qu’on doit réécrire pour chaque
            // problème. Elle doit retourner la liste complète des nœuds successeurs de N.
            List <Noeud> listSucc = N.ObtenirSuccesseurs();

            // Pour chaque nœud de la liste des successeurs
            foreach (Noeud noeudEvalue in listSucc)
            {
                // On vérifie s’il n’est pas une copie d’un nœud déjà vu
                // et placé dans la liste des fermés
                Noeud noeudTrouve = ChercherNoeudDansFermes(noeudEvalue);

                if (noeudTrouve == null)
                {
                    // Si ce n’est pas le cas, on vérifie également s’il n’est pas
                    // une copie d’un nœud déjà vu et placé dans la liste des fermés
                    noeudTrouve = ChercherNoeudDansOuverts(noeudEvalue);

                    if (noeudTrouve != null)
                    {
                        // Il existe, donc on l’a déjà vu.
                        // Le nouveau chemin passant par N est-il meilleur ?
                        if (N.GCout + N.ObtenirCout(noeudEvalue) < noeudTrouve.GCout)
                        {
                            // Mise à jour du nœud trouvé
                            noeudTrouve.GCout = N.GCout + N.ObtenirCout(noeudEvalue);

                            // HCost pas recalculé car toujours bon
                            noeudTrouve.CalculerCoutTotal(); // somme de GCost et HCost

                            // Mise à jour de la famille...
                            noeudTrouve.SupprimerLiensParent();
                            noeudTrouve.Parent(N);

                            // Mise à jour des ouverts
                            noeudsOuverts.Remove(noeudTrouve);
                            this.InsererNoeudDansOuverts(noeudTrouve);
                        }

                        // else on ne fait rien, car le nouveau chemin est moins bon
                    }

                    else
                    {
                        // Le nœud est nouveau. Il faut donc le mettre à jour
                        // et l’insérer dans la liste des ouverts
                        noeudEvalue.GCout = N.GCout + N.ObtenirCout(noeudEvalue);
                        noeudEvalue.CalculerHCout();
                        noeudEvalue.Parent(N);
                        noeudEvalue.CalculerCoutTotal(); // somme de GCost et HCost
                        this.InsererNoeudDansOuverts(noeudEvalue);
                    }
                }

                // else il est dans les fermés donc on ne fait rien,
                // car on a déjà trouvé le plus court chemin pour aller vers le nœud évalué
            }
        }
예제 #2
0
        /// <summary>
        /// Permet de rechercher le plus court chemin
        /// </summary>
        /// <param name="noeudInitial">Nœud de départ</param>
        /// <param name="xFinal">Ligne du nœud d’arrivée</param>
        /// <param name="yFinal">Colonne du nœud d’arrivée</param>
        /// <returns>Liste des nœuds pour aller du départ à l’arrivée</returns>
        public List <Noeud> RechercherSolutionAEtoile(Noeud noeudInitial)
        {
            noeudsOuverts = new List <Noeud>();
            noeudsFermes  = new List <Noeud>();

            Noeud noeud = noeudInitial;

            // On ajoute le nœud de départ aux ouverts
            noeudsOuverts.Add(noeudInitial);

            // Tant que le nœud n’est pas terminal
            // et que la liste des ouverts n’est pas vide
            while (noeudsOuverts.Count != 0 && noeud.VerifierFin() == false)
            {
                // Le meilleur nœud des ouverts est supposé placé
                // en tête de liste des fermés
                noeudsOuverts.Remove(noeud);
                noeudsFermes.Add(noeud);

                // Il faut trouver les nœuds successeurs de N
                this.MettreAJourSuccesseurs(noeud);
                // Inutile de retrier car les insertions ont été faites en respectant l’ordre

                // On prend le meilleur, donc celui en position 0, pour continuer
                // à explorer les états, à condition qu’il existe bien sûr
                if (noeudsOuverts.Count > 0)
                {
                    noeud = noeudsOuverts[0];
                }

                else
                {
                    noeud = null;
                }
            }

            // A* terminé
            // On retourne le chemin qui va du nœud initial au nœud final sous forme de liste
            // Le chemin est retrouvé en partant du nœud final et en accédant aux parents de manière
            // itérative jusqu’à ce qu’on tombe sur le nœud initial
            List <Noeud> _LN = new List <Noeud>();

            if (noeud != null)
            {
                _LN.Add(noeud);

                while (noeud != noeudInitial)
                {
                    noeud = noeud.Parent();
                    _LN.Insert(0, noeud);  // On insère en position 1
                }
            }

            return(_LN);
        }