Advertisement
csaki

MestInt - Jegyzet osztályokról

Mar 25th, 2014
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.74 KB | None | 0 0
  1. AbsztraktÁllapot osztály (absztrakt):
  2. Annak az osztálynak a váza, amely tulajdonképpen a probléma megoldására hozunk létre, dolgozunk ki.
  3. (Érdemes tudni: Immutable = nem változtatható.
  4. Ebben az esetben nem változhat meg a belső állapot. Minden állapotváltoztatás esetén új objektumot hozunk létre.
  5. Szentírás, fogadjátok el, hogy ez jó valamire, hozzám nem ért el ez az információ. :D
  6. Immutable esetén nem kívülről klónozunk hanem belülről (nem kell örökölni az IClonable-t). Azelőtt klónozunk, mielőtt változtatnánk bármin is, így gyakorlatilag elérjük azt, hogy minden példány immutable lesz, tehát a belső állapot nem fog változni, mert minden változtatás előtt készítünk egy klónt, és az új objektumon megy tovább a kísérletezés.)
  7. ######## ZH-ban valószínű, hogy az immutable fog kelleni. ########
  8.  
  9. Állapotokra vonatkozó függvények (abstract):
  10. 1) bool ÁllapotE():
  11. Publikus.
  12. Ez a függvény kidolgozva megmondja, hogy az operátor nem végez-e rossz műveletet. Kicsit nehéz körülírni; a 3 kancsós problémánál szimplán return true van, mert elég nehéz rosszul önteni a kancsóba, viszont az éhes huszár problémánál itt vizsgáljuk hogy a ló pl a margón van-e.
  13.  
  14. 2) bool CélÁllapotE():
  15. Publikus.
  16. Ennek a függvénynek kidolgozott formája mondja meg, hogy elértük-e azt amit szeretnénk, megoldottuk-e a problémát, vagyis hogy terminális csúcson vagyunk-e. A három kancsó probléma terminális csúcsának állapota az, amikor az egyik kancsóban 4 liter víz van. Ekkor a függvény true értékkel tér vissza.
  17.  
  18. Operátorokra vonatkozó függvények (abstract):
  19. 3) int OperátorokSzáma():
  20. Publikus.
  21. Visszatér az operátorok számával (ezt sajátkezűleg kell beállítanod, hogy mennyi).
  22.  
  23. 4) bool/AbszraktÁllapot SzuperOperátor(int i):
  24. Publikus.
  25. A visszatérési érték mutable esetén bool, immutable esetén AbsztraktÁllapot.
  26. Itt vannak felsorolva a lehetséges műveletek, az összes lehetséges operátor; az összes lehetséges kancsóöntés, lólépés, kannibál-szerzetes szállítás.
  27. Az ehhez szükséges függvényt (Töltés, lólépés, stb) nekünk kell kidolgoznunk. A függvény visszatérési értéke a SzuperOperátor függvény visszatérési értékével kell megegyezzen.
  28.  
  29. Egyéb függvények:
  30. 5) virtual object Clone()
  31. Immutable esetén protected, egyébként publikus.
  32. Kidolgozva ez tér vissza a klónozandó elem másolatával (copy-konstruktor).
  33.  
  34. 6) override bool Equals(object o)
  35. Publikus.
  36. Egyenlő a két objektum, ha a belső állapotuk egyenlő.
  37.  
  38. 7) override GetHashCode()
  39. Publikus.
  40. Ha az Equast kidolgozzuk, ki szoktuk ezt is dolgozni. Ez is szentírás (tehát nincs ötletem miért létszükség (nem az, egyébként)), és a VS is warningolni fog miatta.
  41.  
  42. -------------------------------
  43.  
  44. Csúcs osztály:
  45. A gráfkereső által bejárható gráf egy-egy csúcsát reprezentálja.
  46. Mezők:
  47. 1) Csúcs szülő;
  48. Az adott csúcs szülőjét tárolja.
  49. 2) int mélység;
  50. A startcsúcs mélysége 0, az ő közvetlen gyerekének 1, és így tovább...
  51. 3) AbszratkÁllapot állapot;
  52. Az aktuális csúcs belső állapotát tárolja.
  53.  
  54. Konstruktorok:
  55. 1) Kezdőállapot:
  56. public Csúcs(AbsztraktÁllapot kezdőÁllapot)
  57. {
  58. állapot = kezdőÁllapot;
  59. mélység = 0;
  60. szülő = null;
  61. }
  62. 2) Továbbiakban:
  63. 2/a) Mutable:
  64. public Csúcs(Csúcs szülő)
  65. {
  66. állapot = (AbsztraktÁllapot)szülő.állapot.Clone();
  67. mélység = szülő.mélység + 1;
  68. this.szülő = szülő;
  69. }
  70. 2/b) Immutable:
  71. Az új csúcs gyártása előtt klónozunk!
  72. public Csúcs(AbsztraktÁllapot állapot, int mélység, Csúcs szülő)
  73. {
  74. this.állapot = állapot;
  75. this.mélység = mélység;
  76. this.szülő = szülő;
  77. }
  78.  
  79. Függvények (mind publikus):
  80. 1) Csúcs GetSzülő() / int GetMélység()
  81. C#-osabb megoldás lenne a property itt. Csak a mező értékével tér vissza.
  82. return szülő; / return mélység;
  83.  
  84. 2) bool TerminálisCsúcsE()
  85. Egyszerűen meghívja a jelenlegi állapotának a CélÁllapotE() függvényét. Ha ez true, akkor van egy megoldása a keresésnek.
  86. Ez a báziskritériuma a rekurzív keresésnek.
  87.  
  88. 3) int OperátorokSzáma()
  89. Meghívja ugyanezt a függvényt az állapotra.
  90. return állapot.OperátorokSzáma();
  91.  
  92. 4) bool/AbsztraktÁllapot SzuperOperátor(int i);
  93. 4/a) Mutable:
  94. Meghívja ugyanezt a függvényt az állapotra.
  95. return állapot.SzuperOperátor(i);
  96. 4/b) Immutable:
  97. Gyártunk egy új állapotot (belső klónozás) a függvény hívásával.
  98. AbsztraktÁllapot új = állapot.SzuperOperátor(i); // ez lesz az új állapot, amit visszaadott a szuperoperátor
  99. if (új != null) { return new Csúcs(új, mélység + 1, this); } // az immutable konstruktornak megfelelően így térünk vissza az új csúccsal
  100. else return null; // null, ha egyik szuperoperátor sem volt jó
  101.  
  102. 5) bool Equals(object o)
  103. Két csúcs akkor egyenlő, ha az állapotuk egyenlő. Tehát: meghívjuk az állapot.Equals-t ugyanígy!
  104.  
  105. 6) int GetHashCode()
  106. Az előzőhöz hasonlóan az állapot hash kódjával térünk vissza.
  107.  
  108. 7) string ToString()
  109. Itt is: az állapot ToString függvényét hívjuk meg.
  110.  
  111. -------------------------------
  112.  
  113. Gráfkereső osztály (absztrakt):
  114. Egy gráfkereső (pl. backtrack) algoritmus váza.
  115.  
  116. Mezők:
  117. 1) Csúcs startCsúcs;
  118. A gráf gyökere, a start.
  119.  
  120. Konstruktor:
  121. Csak a startCsúcsot kell beállítani, ahonnan a kereső keresni fog.
  122.  
  123. Függvények:
  124. 1) Csúcs GetStartCsúcs()
  125. Protected.
  126. Megint csak propertyvel lenne szebb, dehát a java átka.... a startcsúccsal tér vissza.
  127. 2) Keresés() (absztrakt)
  128. Publikus.
  129. Override-olandó, itt hajtódik végre minden lényeges művelet.
  130.  
  131. 3) void MegoldásKiírása(Csúcs csúcs)
  132. Publikus.
  133. Két eset lehetséges: vagy van megoldás, vagy nincs. Ha van megoldás, a függvénynek átadott Csúcs objektum nem lesz null. Ha nincs megoldás, akkor a csúcs null, ekkor ezt kiíratjuk és kilépünk (return).
  134. Ha van megoldás, akkor meg kell fordítani a csúcsok sorrendjét, amit megjegyzett a kereső, hogy a kiíratás ne fordított sorrendben történjen. Ez egy veremmel könnyen megvalósítható: belepakolod sorban, és fordított sorrendben kiolvasod. Addig kéred le a csúcs szülőjét, amíg el nem éred a start csúcsot (a startcsúcs szülője null).
  135. Stack<Csúcs> megoldás = new Stack<Csúcs>();
  136. Csúcs aktCsúcs = csúcs;
  137. while (aktCsúcs != null)
  138. {
  139. megoldás.Push(aktCsúcs);
  140. aktCsúcs = aktCsúcs.GetSzülő();
  141. }
  142. ...és ezután szépen kiíratjuk őket sorban.
  143. foreach (Csúcs akt in megoldás)
  144. Console.WriteLine(akt);
  145.  
  146. -------------------------------
  147.  
  148. BackTrack osztály (örökli a GráfKereső osztályt):
  149. A visszalépéses keresést megvalósító gráfkereső osztály.
  150.  
  151. Mezők:
  152. 1) Csúcs startCsúcs;
  153. Örökölt.
  154. 2) bool emlékezetes;
  155. Hogy emlékezetes backtracket szeretnénk-e avagy sem.. (emlékezetes: megjegyzi a szülőket, tudva ezzel az útvonalat, ahogyan eljutott a csúcsig. Enélkül nem tudnánk kiíratni a megoldáshoz vezető utat.)
  156. 3) int korlát;
  157. Hogy korlátos backtracket szeretnénk-e avagy sem.. (korlát: egy bizonyos mélységi határ, aminél messzebb már nem keres tovább a gráfkereső)
  158.  
  159. Konstruktorok:
  160. 1) A háromparaméteres konstruktor a "fő", az hívja meg az ősosztály konstruktorát, ahol beállítjuk a startcsúcsot. A többi mező úgyis csak a backtrack osztályban létezik. A többi konstruktor meghívja ezt a konstruktort, a hiányzó paramétert pótolva egy 0-val a korlát esetén, false-al az emlékezetes esetén.
  161. public BackTrack(Csúcs startCsúcs, int korlát, bool emlékezetes)
  162. : base(startCsúcs)
  163. {
  164. this.korlát = korlát;
  165. this.emlékezetes = emlékezetes;
  166. }
  167. Továbbiak:
  168. 2) Emlékezetes, nem korlátolt
  169. 3) Nem emlékezetes, korlátos
  170.  
  171. Függvények:
  172. 1) Egy függvény van, a keresés.
  173. 1/a) A paraméter nélküli publikus, ez a gyökérelemtől elkezdi a keresést.
  174. Ez kapásból meghívja a paraméterezett keresés függvényt, csak a startcsúcsot adja át neki. (return Keresés(GetStartCsúcs());).
  175. 1/b) A paraméterezett privát, ez egy adott csúcsból kezd el keresni.
  176. Folyamata:
  177. 1) Lekérdezi az aktuális mélységet.
  178. 2) Megvizsgálja, hogy korlátos backtrackről van-e szó (korlát > 0 [korlát = 0, ha nem korlátos]), és ha igen, akkor kívül esett-e már a keresés a mélységen (mélység >= korlát). Ha igen, nullal tér vissza.
  179. 3) Megvizsgálja, hogy emlékezetes backtrack-e, s ha igen, eltárolja a szülőt (aktSzülő = aktCsúcs.GetSzülő();),
  180. 4) Végigfut egy while ciklus ami a körfigyeléshez kell. Megnézi, hogy az aktuális úton szerepelt-e már az aktuális csúcs. Ha igen akkor visszalép, hiszen körbe került (volt min. 2x ugyan az a csúcs).
  181. 5) Báziskritérium!! Megnézi hogy az aktuális csúcs terminális csúcs-e, vagyis hogy a csúcs állapota célállapotban van-e. (Ez esetben visszatér az aktuális csúccsal.)
  182. 6) Indul egy forciklus, ami gyakorlatilag végignézi az aktuális csúcs gyerekelemeit. A ciklus az operátorok számáig megy.
  183. Mutable:
  184. 1) Gyárt egy új csúcsot (copy konstruktor)
  185. 2) Megnézi hogy alkalmazható-e az i. operátor
  186. 3) Ha nem, pörög egyet a ciklus, növeljük az i-t egyel
  187. 4) Ha igen, akkor indul egy új rekurzió, onnan folytatva tovább a keresést.
  188. 5) Ha egy keresés befejeződött, megnézzük, hogy a csúcs amivel visszatért a keresés, terminális-e (nem egyenlő nullal).
  189. 6) Ha igen, akkor visszaadjuk a csúcsot, mint terminális csúcsot.
  190. 7) Ha nem, akkor folytatjuk a keresést tovább.
  191. 8) Ha elfogytak az operátorok, a keresés nullal tér vissza. Ha a legfelső keresés is nullal tér vissza, nincs megoldás.
  192. Immutable:
  193. A folyamat hasonló az előzőhöz, néhány különbséggel.
  194. 1) Gyárt egy új csúcsot, ami a szuperoperátor visszatérési értéke. (Csúcs újCsúcs = aktCsúcs.SzuperOperátor(i);)
  195. 2) Megnézi hogy az új csúcs null-e (alkalmazható volt-e az operátor)
  196. 3) Ha nem, megy tovább a ciklus
  197. 4) Ha igen, indul egy újabb rekurzió az új csúcsból.
  198. ....de innen minden ugyanaz, mint a mutable esetén.
  199.  
  200. -------------------------------
  201.  
  202. Főprogram:
  203. 1) Startcsúcs példányosítása (Csúcs konstruktorába ugye egy absztraktállapot-kompatibilis példány kell, pölö: Csúcs startcsúcs = new Csúcs(new HáromKancsóÁllapot()));
  204. 2) Gráfkereső példányosítása (péééééldául BackTrack, aminek át kell adni a startcsúcsot, opcionálisan a korlátot és azt, hogy emlékezetes legyen-e)
  205. 3) kereső.MegoldásKiírása(kereső.Keresés());
  206.  
  207. És.... ennyi!
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement