Exemplo n.º 1
0
        public void RechercheSolutionAEtoile()
        {
            int    numEtape = 1;
            Sommet s        = SommetInitial;

            SommetsOuverts.Add(s);
            EtatsSuccessifsOuverts.Add(DeepCopy(SommetsOuverts));
            EtatsSuccessifsFermes.Add(DeepCopy(SommetsFermes));
            // tant que le noeud n'est pas terminal et que ouverts n'est pas vide
            while (SommetsOuverts.Count != 0 && s.EndState() == false)
            {
                // Le meilleur noeud des ouverts est supposé placé en tête de liste
                // On le place dans les fermés
                SommetsOuverts.Remove(s);
                SommetsFermes.Add(s);

                // Il faut trouver les noeuds successeurs de s
                MAJSuccesseurs(s, numEtape);
                // 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
                // A condition qu'il existe bien sûr
                if (SommetsOuverts.Count > 0)
                {
                    s = SommetsOuverts.First();
                }
                else
                {
                    s = null;
                }
                EtatsSuccessifsOuverts.Add(DeepCopy(SommetsOuverts));
                EtatsSuccessifsFermes.Add(DeepCopy(SommetsFermes));
                numEtape++;
            }
            SommetsOuverts.Remove(SommetFinal);
            SommetsFermes.Add(SommetFinal);
            EtatsSuccessifsOuverts.Add(SommetsOuverts);
            EtatsSuccessifsFermes.Add(SommetsFermes);
            // A* terminé
            // On retourne le chemin qui va du noeud initial au noeud final sous forme de liste
            // Le chemin est retrouvé en partant du noeud final et en accédant aux parents de manière
            // itérative jusqu'à ce qu'on tombe sur le noeud initial
            if (s != null)
            {
                PlusCourtChemin.Add(s);
                CoutPlusCourtChemin = s.CoutTotal;
                while (!s.IsEqual(SommetInitial))
                {
                    s = s.SommetParent;
                    PlusCourtChemin.Insert(0, s);  // On insère en position 1
                }
            }
        }
Exemplo n.º 2
0
        private void MAJSuccesseurs(Sommet s, int numEtape)
        {
            // On fait appel à GetListSucc, méthode abstraite qu'on doit réécrire pour chaque
            // problème. Elle doit retourner la liste complète des noeuds successeurs de s.
            List <Sommet> listsucc = s.GetSuccesseurs();

            foreach (Sommet succ in listsucc)
            {
                // succ est-il une copie d'un nœud déjà vu et placé dans la liste des fermés ?
                Sommet succBis = SommetsFermes.Find(x => x.IsEqual(succ));
                if (succBis == null)
                {
                    // Rien dans les fermés. Est-il dans les ouverts ?
                    succBis = SommetsOuverts.Find(x => x.IsEqual(succ));
                    if (succBis != null)
                    {
                        // Il existe, donc on l'a déjà vu, succ n'est qu'une copie de N2Bis
                        // Le nouveau chemin passant par s est-il meilleur ?
                        if (s.CoutCumule + RetrouveArete(s, succ).Cout < succBis.CoutCumule)
                        {
                            // Mise à jour de succBis
                            succBis.CoutCumule = s.CoutCumule + RetrouveArete(s, succ).Cout;
                            // HCost pas recalculé car toujours bon
                            succBis.RecalculeCoutTotal(); // somme de CoutCumule et CoutHeuristique
                            // Mise à jour de la famille ....
                            succBis.SupprimeLienParent();
                            succBis.SommetParent = s;
                            // Mise à jour des ouverts
                            SommetsOuverts.Remove(succBis);
                            InsertNewNodeInOpenList(succBis, numEtape);
                        }
                        // else on ne fait rien, car le nouveau chemin est moins bon
                    }
                    else
                    {
                        // succ est nouveau, MAJ et insertion dans les ouverts
                        succ.CoutCumule   = s.CoutCumule + RetrouveArete(s, succ).Cout;
                        succ.SommetParent = s;
                        succ.CalculCoutTotal(); // somme de GCost et HCost
                        InsertNewNodeInOpenList(succ, numEtape);
                    }
                }
                // else il est dans les fermés donc on ne fait rien,
                // car on a déjà trouvé le plus court chemin pour aller en succ
            }
        }