Advertisement
csaki

MestInt - Vikiféle

Mar 25th, 2014
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.43 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. abstract class AbsztraktÁllapot
  7. {
  8.     public abstract bool ÁllapotE();
  9.     public abstract bool CélÁllapotE();
  10.     public abstract int OperátorokSzáma();
  11.     // bool helyére AbsztraktÁllapot kell a másik megoldás szerint
  12.     // cél: immutable legyen --> a belső állapota nem fog megváltozni
  13.     public abstract AbsztraktÁllapot SzuperOperátor(int i);
  14.     // kívülről így már nem kell meghívni a klónozást, de belül kell!!
  15.     // az előtt kell klónozni, mielőtt megcsinálod a változtatást
  16.     // mert a klónozás akkor kell, ha azt akarom, hogy az egyik változása ne változtasson a másikon
  17.     // és ha immutable, akkor ne mtudom megváltoztatni
  18.     // : ICloneable nem kell
  19.     // így már a klónozás lehet protected
  20.     protected virtual object Clone() { return MemberwiseClone(); }
  21.     public override bool Equals(Object a) { return false; }
  22.     public override int GetHashCode() { return base.GetHashCode(); }
  23. }
  24.  
  25. class Csúcs
  26. {
  27.     AbsztraktÁllapot állapot;
  28.     int mélység;
  29.     Csúcs szülő;
  30.     public Csúcs(AbsztraktÁllapot kezdőÁllapot)
  31.     {
  32.         állapot = kezdőÁllapot;
  33.         mélység = 0;
  34.         szülő = null;
  35.     }
  36.     // itt van változás!!!!
  37.     public Csúcs(AbsztraktÁllapot állapot, int mélység, Csúcs szülő) //állapot --> új
  38.     {
  39.         this.állapot = állapot;
  40.         this.mélység = mélység;
  41.         this.szülő = szülő;
  42.     }
  43.     public Csúcs GetSzülő() { return szülő; }
  44.     public int GetMélység() { return mélység; }
  45.     public bool TerminálisCsúcsE() { return állapot.CélÁllapotE(); }
  46.     public int OperátorokSzáma() { return állapot.OperátorokSzáma(); }
  47.     // itt van változás!!!
  48.     public Csúcs SzuperOperátor(int i)
  49.     {
  50.         AbsztraktÁllapot új = állapot.SzuperOperátor(i); //az lesz az új állapot, amit visszaadott a szuperoperátor
  51.         if (új != null) return new Csúcs(új, mélység + 1, this);
  52.         return null;
  53.     }
  54.     public override bool Equals(Object obj)
  55.     {
  56.         // 2 csúcs akkor egyenlő, ha a bennük lévő állapot megegyezik
  57.         Csúcs cs = (Csúcs)obj;
  58.         return állapot.Equals(cs.állapot);
  59.     }
  60.     public override int GetHashCode() { return állapot.GetHashCode(); }
  61.     public override String ToString() { return állapot.ToString(); }
  62.    
  63. }
  64.  
  65. abstract class GráfKereső
  66. {
  67.     private Csúcs startCsúcs;
  68.     public GráfKereső(Csúcs startCsúcs)
  69.     {
  70.         this.startCsúcs = startCsúcs;
  71.     }
  72.     protected Csúcs GetStartCsúcs() { return startCsúcs; }
  73.     public abstract Csúcs Keresés();
  74.     public void megoldásKiírása(Csúcs egyTerminálisCsúcs)
  75.     {
  76.         if (egyTerminálisCsúcs == null)
  77.         {
  78.             Console.WriteLine("Nincs megoldás");
  79.             return;
  80.         }
  81.         Stack<Csúcs> megoldás = new Stack<Csúcs>();
  82.         Csúcs aktCsúcs = egyTerminálisCsúcs;
  83.         while (aktCsúcs != null)
  84.         {
  85.             megoldás.Push(aktCsúcs);
  86.             aktCsúcs = aktCsúcs.GetSzülő();
  87.         }
  88.         foreach (Csúcs akt in megoldás) Console.WriteLine(akt);
  89.     }
  90. }
  91.  
  92. class BackTrack : GráfKereső
  93. {
  94.     int korlát;
  95.     bool emlékezetes;
  96.     public BackTrack(Csúcs startCsúcs, int korlát, bool emlékezetes)
  97.         : base(startCsúcs)
  98.     {
  99.         this.korlát = korlát;
  100.         this.emlékezetes = emlékezetes;
  101.     }
  102.     public BackTrack(Csúcs startCsúcs) : this(startCsúcs, 0, false) { }
  103.     public BackTrack(Csúcs startCsúcs, int korlát) : this(startCsúcs, korlát, false) { }
  104.     public BackTrack(Csúcs startCsúcs, bool emlékezetes) : this(startCsúcs, 0, emlékezetes) { }
  105.     public override Csúcs Keresés() { return Keres(GetStartCsúcs()); }
  106.  
  107.     private Csúcs Keresés(Csúcs aktCsúcs)
  108.     {
  109.         Stack<int> operatstack = new Stack<int>();
  110.         int aktop = 0;
  111.         while (aktCsúcs != null)
  112.         {
  113.             if (aktCsúcs.TerminálisCsúcsE()) return aktCsúcs;
  114.             int operatorszam = aktCsúcs.OperátorokSzáma();
  115.             for (; aktop < operatorszam; aktop++)
  116.             {
  117.                 bool jartamitt = false;
  118.                 Csúcs vizsgalt = aktCsúcs.GetSzülő();
  119.                 while (vizsgalt != null)
  120.                 {
  121.                     if (aktCsúcs.Equals(vizsgalt))
  122.                     {
  123.                         jartamitt = true;
  124.                         break;
  125.                     }
  126.                     vizsgalt = vizsgalt.GetSzülő();
  127.                 }
  128.                 Csúcs nextcsúcs = aktCsúcs.SzuperOperátor(aktop);
  129.                 if (nextcsúcs != null && !jartamitt)
  130.                 {
  131.                     operatstack.Push(aktop);
  132.                     aktop = -1;
  133.                     aktCsúcs = nextcsúcs;
  134.                 }
  135.             }
  136.             aktCsúcs = aktCsúcs.GetSzülő();
  137.             try
  138.             {
  139.                 aktop = operatstack.Pop() + 1;
  140.             }
  141.             catch (InvalidOperationException)
  142.             {
  143.                 return null;
  144.             }
  145.         }
  146.         return null;
  147.     }
  148.  
  149.     // ebben can változás!
  150.     private Csúcs Keres(Csúcs aktCsúcs)
  151.     {
  152.         int mélység = aktCsúcs.GetMélység();
  153.         //úgy mondod, hogy nincs korlátos (mert az a mélységi korlátos backtrackhez kell), hogy korlát=0
  154.         if (korlát > 0 && mélység >= korlát) return null;
  155.         Csúcs aktSzülő = null;
  156.         if (emlékezetes) aktSzülő = aktCsúcs.GetSzülő();
  157.         while (aktSzülő != null)
  158.         {
  159.             if (aktCsúcs.Equals(aktSzülő)) return null;
  160.             aktSzülő = aktSzülő.GetSzülő();
  161.         }
  162.         // ő a bázisfeltétel, ez fogja megállítani a rekurziót
  163.         if (aktCsúcs.TerminálisCsúcsE())
  164.         {
  165.             return aktCsúcs;
  166.         }
  167.         for (int i = 0; i < aktCsúcs.OperátorokSzáma(); i++) // kipróbálja az összes operátort
  168.         {
  169.             Csúcs újCsúcs = aktCsúcs.SzuperOperátor(i); // az új csúcsot úgy kapom meg az aktuális csúcsból, hogy előremegyek a szuperoperátorral
  170.             if (újCsúcs!=null)
  171.             {
  172.                 Csúcs terminális = Keres(újCsúcs);
  173.                 if (terminális != null)
  174.                 {
  175.                     return terminális;
  176.                 }
  177.             }
  178.         }
  179.         return null;
  180.     }
  181. }
  182.  
  183. class ÉhesHuszárÁllapot : AbsztraktÁllapot
  184. {
  185.     static int N = 3;
  186.     int x, y;
  187.     public ÉhesHuszárÁllapot()
  188.     {
  189.         x = 2; // A bal felső sarokból indulunk, ami a margó
  190.         y = 2; // miatt a (2,2) koordinátán van.
  191.     }
  192.     public ÉhesHuszárÁllapot(int n)
  193.     {
  194.         x = 2;
  195.         y = 2;
  196.         N = n;
  197.     }
  198.     public override bool CélÁllapotE()
  199.     {
  200.         // A jobb alsó sarok a margó miatt a (N+1,N+1) helyen van.
  201.         return x == N + 1 && y == N + 1;
  202.     }
  203.     public override bool ÁllapotE()
  204.     {
  205.         // a ló nem a margon van
  206.         return x >= 2 && y >= 2 && x <= N + 1 && y <= N + 1;
  207.     }
  208.     private bool preLóLépés(int x, int y)
  209.     {
  210.         // jó lólépés-e, ha nem akkor return false
  211.         if (!(x * y == 2 || x * y == -2)) return false;
  212.         return true;
  213.     }
  214.     // ebben van változás!!!
  215.     private AbsztraktÁllapot lóLépés(int x, int y)
  216.     {
  217.         if (!preLóLépés(x, y)) return null;
  218.         ÉhesHuszárÁllapot új = (ÉhesHuszárÁllapot)this.Clone(); //vagy copy konstruktorral
  219.         új.x += x;
  220.         új.y += y;
  221.         if (új.ÁllapotE()) return új;
  222.         return null;
  223.         // így nem helyben történik meg az átmenet, hanem az újban!!!
  224.         // és innentől fogva immutable
  225.         // ha így írjuk meg, az újnak kell hívni az ÁllapotE() fv.-ét
  226.     }
  227.     // itt van változás!!!
  228.     public override AbsztraktÁllapot SzuperOperátor(int i)
  229.     {
  230.         switch (i)
  231.         { // itt sorolom fel a lehetséges 8 lólépést
  232.             case 0: return lóLépés(1, 2);
  233.             case 1: return lóLépés(1, -2);
  234.             case 2: return lóLépés(-1, 2);
  235.             case 3: return lóLépés(-1, -2);
  236.             case 4: return lóLépés(2, 1);
  237.             case 5: return lóLépés(2, -1);
  238.             case 6: return lóLépés(-2, 1);
  239.             case 7: return lóLépés(-2, -1);
  240.             default: return null; // ez jelenti azt, hogy nem sikerült
  241.         }
  242.     }
  243.     public override int OperátorokSzáma() { return 8; }
  244.     // A kiíratásnál kivonom x-ből és y-ból a margó szélességét.
  245.     public override string ToString() { return (x - 2) + " : " + (y - 2); }
  246.     public override bool Equals(Object a)
  247.     {
  248.         ÉhesHuszárÁllapot aa = (ÉhesHuszárÁllapot)a;
  249.         return aa.x == x && aa.y == y;
  250.     }
  251.     // Ha két példány egyenlő, akkor a hasítókódjuk is egyenlő.
  252.     public override int GetHashCode()
  253.     {
  254.         return x.GetHashCode() + y.GetHashCode();
  255.     }
  256. }
  257.  
  258.     class Program
  259.     {
  260.         static void Main(string[] args)
  261.         {
  262.             Csúcs startCsúcs;
  263.             GráfKereső kereső;
  264.             Console.WriteLine("Éheshuszár probléma:");
  265.             startCsúcs = new Csúcs(new ÉhesHuszárÁllapot(8));
  266.             kereső = new BackTrack(startCsúcs, 10, true);
  267.             kereső.megoldásKiírása(kereső.Keresés());
  268.             Console.ReadLine();
  269.         }
  270.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement