Example #1
0
 private Csúcs TerminálisCsúcsKeresés()
 {
     // Amíg a nyílt csúcsok halmaza nem nem üres.
     while (Nyilt.Count != 0)
     {
         // Ez a legnagyobb mélységű nyílt csúcs.
         Csúcs C = Nyilt.Pop();
         // Ezt kiterjesztem.
         List <Csúcs> újCsucsok = C.Kiterjesztes();
         foreach (Csúcs D in újCsucsok)
         {
             // Ha megtaláltam a terminális csúcsot, akkor kész vagyok.
             if (D.TerminálisCsúcsE())
             {
                 return(D);
             }
             // Csak azokat az új csúcsokat veszem fel a nyíltak közé,
             // amik nem szerepeltek még sem a zárt, sem a nyílt csúcsok halmazában.
             // A Contains a Csúcs osztályban megírt Equals metódust hívja.
             if (!Zárt.Contains(D) && !Nyilt.Contains(D))
             {
                 Nyilt.Push(D);
             }
         }
         // A kiterjesztett csúcsot átminősítem zárttá.
         Zárt.Add(C);
     }
     return(null);
 }
Example #2
0
 bool körFigyelés;    // Ha hamis, végtelen ciklusba eshet.
 public MélységiKeresés(Csúcs startCsúcs, bool körFigyelés) :
     base(startCsúcs)
 {
     Nyilt = new Stack <Csúcs>();
     Nyilt.Push(startCsúcs);                // kezdetben csak a start csúcs nyílt
     Zárt             = new List <Csúcs>(); // kezdetben a zárt csúcsok halmaza üres
     this.körFigyelés = körFigyelés;
 }
Example #3
0
        static void Main(string[] args)
        {
            Csúcs      startCsúcs;
            GráfKereső kereső;

            AbsztraktÁllapot k = new BuvosKeresztAllapot();

            startCsúcs = new Csúcs(k);

            Console.WriteLine("A kereső egy 20 mélységi korlátos és emlékezetes backtrack.");
            kereső = new BackTrack(startCsúcs, 20, true);
            kereső.megoldásKiírása(kereső.Keresés());

            Console.ReadLine();
        }
Example #4
0
        // Alkalmazza az összes alkalmazható operátort.
        // Visszaadja az így előálló új csúcsokat.
        public List <Csúcs> Kiterjesztes()
        {
            List <Csúcs> újCsúcsok = new List <Csúcs>();

            for (int i = 0; i < OperátorokSzáma(); i++)
            {
                // Új gyermek csúcsot készítek.
                Csúcs újCsúcs = new Csúcs(this);
                // Kiprobálom az i.dik alapoperátort. Alkalmazható?
                if (újCsúcs.SzuperOperátor(i))
                {
                    // Ha igen, hozzáadom az újakhoz.
                    újCsúcsok.Add(újCsúcs);
                }
            }
            return(újCsúcsok);
        }
Example #5
0
 // Ezt csak akkor szabad használni, ha biztos, hogy az állapottér gráfban nincs kör!
 // Különben valószínűleg végtelen ciklust okoz.
 private Csúcs TerminálisCsúcsKeresésGyorsan()
 {
     while (Nyilt.Count != 0)
     {
         Csúcs        C         = Nyilt.Pop();
         List <Csúcs> ujCsucsok = C.Kiterjesztes();
         foreach (Csúcs D in ujCsucsok)
         {
             if (D.TerminálisCsúcsE())
             {
                 return(D);
             }
             // Ha nincs kör, akkor felesleges megnézni, hogy D volt-e már nyíltak vagy a zártak közt.
             Nyilt.Push(D);
         }
         // Ha nincs kör, akkor felesleges C-t zárttá minősíteni.
     }
     return(null);
 }
Example #6
0
        /// <summary>
        /// Kiíratja a megoldást egy terminális csúcs alapján.
        /// Feltételezi, hogy a terminális csúcs szülő referenciáján felfelé haladva eljutunk a start csúcshoz.
        /// A csúcsok sorrendjét megfordítja, hogy helyesen tudja kiírni a megoldást.
        /// Ha a csúcs null, akkor kiírja, hogy nincs megoldás.
        /// </summary>
        /// <param name="egyTerminálisCsúcs">
        /// A megoldást képviselő terminális csúcs vagy null.
        /// </param>
        public void megoldásKiírása(Csúcs egyTerminálisCsúcs)
        {
            if (egyTerminálisCsúcs == null)
            {
                Console.WriteLine("Nincs megoldás");
                return;
            }
            // Meg kell fordítani a csúcsok sorrendjét.
            Stack <Csúcs> megoldás = new Stack <Csúcs>();
            Csúcs         aktCsúcs = egyTerminálisCsúcs;

            while (aktCsúcs != null)
            {
                megoldás.Push(aktCsúcs);
                aktCsúcs = aktCsúcs.GetSzülő();
            }
            // Megfordítottuk, lehet kiírni.
            foreach (Csúcs akt in megoldás)
            {
                Console.WriteLine(akt);
            }
        }
Example #7
0
 // A körfigyelés alapértelmezett értéke igaz.
 public MélységiKeresés(Csúcs startCsúcs) : this(startCsúcs, true)
 {
 }
Example #8
0
        // A kereső algoritmus rekurzív megvalósítása.
        // Mivel rekurzív, ezért a visszalépésnek a "return null" felel meg.
        private Csúcs Keresés(Csúcs aktCsúcs)
        {
            int mélység = aktCsúcs.GetMélység();

            // mélységi korlát vizsgálata
            if (korlát > 0 && mélység >= korlát)
            {
                return(null);
            }
            // emlékezet használata kör kiszűréséhez
            Csúcs aktSzülő = null;

            if (emlékezetes)
            {
                aktSzülő = aktCsúcs.GetSzülő();
            }
            while (aktSzülő != null)
            {
                // Ellenőrzöm, hogy jártam-e ebben az állapotban. Ha igen, akkor visszalépés.
                if (aktCsúcs.Equals(aktSzülő))
                {
                    return(null);
                }
                // Visszafelé haladás a szülői láncon.
                aktSzülő = aktSzülő.GetSzülő();
            }
            if (aktCsúcs.TerminálisCsúcsE())
            {
                // Megvan a megoldás, vissza kell adni a terminális csúcsot.
                return(aktCsúcs);
            }
            // Itt hívogatom az alapoperátorokat a szuper operátoron
            // keresztül. Ha valamelyik alkalmazható, akkor új csúcsot
            // készítek, és meghívom önmagamat rekurzívan.
            for (int i = 0; i < aktCsúcs.OperátorokSzáma(); i++)
            {
                // Elkészítem az új gyermek csúcsot.
                // Ez csak akkor lesz kész, ha alkalmazok rá egy alkalmazható operátort is.
                Csúcs újCsúcs = new Csúcs(aktCsúcs);
                // Kipróbálom az i.dik alapoperátort. Alkalmazható?
                if (újCsúcs.SzuperOperátor(i))
                {
                    // Ha igen, rekurzívan meghívni önmagam az új csúcsra.
                    // Ha nem null értéket ad vissza, akkor megvan a megoldás.
                    // Ha null értéket, akkor ki kell próbálni a következő alapoperátort.

                    Csúcs terminális = Keresés(újCsúcs);
                    if (terminális != null)
                    {
                        // Visszaadom a megoldást képviselő terminális csúcsot.
                        return(terminális);
                    }
                    // Az else ágon kellene visszavonni az operátort.
                    // Erre akkor van szükség, ha az új gyermeket létrehozásában nem lenne klónozást.
                    // Mivel klónoztam, ezért ez a rész üres.
                }
            }
            // Ha kipróbáltam az összes operátort és egyik se vezetett megoldásra, akkor visszalépés.
            // A visszalépés hatására eggyel feljebb a következő alapoperátor kerül sorra.
            return(null);
        }
Example #9
0
 // emlékezetes kereső
 public BackTrack(Csúcs startCsúcs, bool emlékezetes) : this(startCsúcs, 0, emlékezetes)
 {
 }
Example #10
0
 // mélységi korlátos kereső
 public BackTrack(Csúcs startCsúcs, int korlát) : this(startCsúcs, korlát, false)
 {
 }
Example #11
0
 // nincs mélységi korlát, se emlékezet
 public BackTrack(Csúcs startCsúcs) : this(startCsúcs, 0, false)
 {
 }
Example #12
0
 bool emlékezetes; // Ha igaz, emlékezetes kereső.
 public BackTrack(Csúcs startCsúcs, int korlát, bool emlékezetes) : base(startCsúcs)
 {
     this.korlát      = korlát;
     this.emlékezetes = emlékezetes;
 }
Example #13
0
 private Csúcs startCsúcs; // A start csúcs csúcs.
                           // Minden gráfkereső a start csúcsból kezd el keresni.
 public GráfKereső(Csúcs startCsúcs)
 {
     this.startCsúcs = startCsúcs;
 }
Example #14
0
        public override bool Equals(Object obj)
        {
            Csúcs cs = (Csúcs)obj;

            return(állapot.Equals(cs.állapot));
        }
Example #15
0
 // Egy új gyermek csúcsot készít.
 // Erre még meg kell hívni egy alkalmazható operátor is, csak azután lesz kész.
 public Csúcs(Csúcs szülő)
 {
     állapot    = (AbsztraktÁllapot)szülő.állapot.Clone();
     mélység    = szülő.mélység + 1;
     this.szülő = szülő;
 }
Example #16
0
 Csúcs szülő; // A szülőkön felfelé haladva a start csúcsig jutok.
              // Konstruktor:
              // A belső állapotot beállítja a start csúcsra.
              // A hívó felelőssége, hogy a kezdő állapottal hívja meg.
              // A start csúcs mélysége 0, szülője nincs.
 public Csúcs(AbsztraktÁllapot kezdőÁllapot)
 {
     állapot = kezdőÁllapot;
     mélység = 0;
     szülő   = null;
 }