Nemes ürességről árulkodott. azonban elégtelen szint*a cenzúra által kivágott* kitolta a megjelenés dátumát, és csak most, részemről szégyenletes, unalmas könyörgés után kapott lehetőséget ez a cikk, hogy megmutassa magát a világnak. Ez alatt az idő alatt legalább három (ennyire akadt meg a szemem) cikk hasonló téma, és valószínűleg nem ez az első alkalom, hogy az alábbiakban leírtak egy részét olvassa el. Azt javaslom az ilyen embereknek, hogy ne ráncolják a szemöldöküket egy tapasztalatlan fiatal újabb próbálkozása előtt, hogy a GA-t népszerűsítő tudományos módon magyarázzák el, hanem térjenek át a következő kiállításra, a második részre, amely egy GA-alapú bot létrehozását írja le. a Robocode programozó játék. Ezzel a legfrissebb titkosszolgálati információk szerint még nem találkoztak a hubon.
Ha a helyzet egyszerű, és egy ilyen probléma megoldása egyértelműen kiszámítható a feltételekből ezeknek a matánoknak a segítségével, akkor nagyszerű, itt minden rendben van a bölcsességünk nélkül is, meg vagyunk szarva, mindannyian külön járunk módokon. Például megoldáskor másodfokú egyenlet a választ (x1, x2 értékek) a kezdeti feltételből (a, b, c együtthatók) kapjuk meg az iskolában tanult képlet alkalmazásával. Mit kell tenni szomorúbb esetben, mikor a szükséges képletet nincs benne a tankönyvben? Kipróbálhatod vele ötletelés megoldja az egyik problémát. Analitikusan. Numerikus módszerek. A funkciók kétségbeesett keresésének erejével. Egy idő után megszólal az álmodozó diák, „ha megoldódik magától”. Igen, itt jövünk ki a függöny mögül. Tehát a cél egy olyan program megírása, amely talál egy függvényt (programot), amely bemeneti adatokat fogad és érvényes számokat ad vissza. A metaprogramozás ereje, harcba!
Hmm, hogyan fogjuk elérni ezt a célt? A tűz mellett hozzunk áldozatot a rekurzió isteneinek: írunk egy programot, ami megír egy függvényt (programot)... Nem, ez másodszorra nem megy. Jobb, ha a természetből veszünk példát, és olyan jelenségekre vetjük tekintetünket, mint az evolúció mechanizmusa, természetes kiválasztódás. Minden olyan, mint az életben: a programjaink az alkalmazkodóbb egyedek igája alatt élnek, párosodnak, szülnek és meghalnak, továbbadva őket. legjobb tulajdonságait leszármazottak. Őrülten hangzik, de érdemes közelebbről is megnézni.
Szoftvervilágunk Istene a mi feladatunk. A programoknak hinniük kell benne, párodni kell érte, gyertyát gyújtani érte a templomban, és együtt kell élni vele egyetlen célja- megtalálni az élet értelmét és megoldani ezt a problémát. Aki a legjobban alkalmazkodik a környezethez (közelebb van a probléma megoldásához), az alfahímmé válik, túléli és erős utódokat hoz. Egy vesztes, aki egész életét börtönben töltötte online játékok nem tapasztalt sikert a probléma megoldásában, nagyon kicsi az esélye, hogy utódokat szüljön. A génállomány megtisztul e pattanásos elvtársak hozzájárulásától, és az egész műsortársadalom megmozdul a megoldott probléma fényes jövője felé. Hát be általános vázlat Már világos, most meg kell értened az árnyalatokat: először is, hogyan képzeled el a programok párosítását? másodszor, honnan szerezzük be a programok első generációját? harmadszor, milyen jellemző alapján határozzuk meg az egyedek alkalmasságát, és hogyan befolyásolja a keresztezést? negyedszer, érdemes eldönteni, hogy milyen feltételekkel zárul az algoritmus, és mikor kell leállítani ezt az egész orgiát.
A programok keresztezésének kérdése nem ilyen egyszerű. A függvények, karakterláncok vagy változók véletlen cseréje kövér szálat eredményez ijesztő szavak neked címezte a fordító/tolmács, és nem új program. Azaz meg kell találni a módot a programok keresztezésére helyesen. Az okos srácok megtalálták a kiutat. És az okos fiúk és lányok, akik a fordítók szerkezetét tanulmányozták, szintén sejtették. Igen, igen, ez egy szintaktikai fa.
Hadd fékezzem meg azonnal a lelkesedésemet: még nem túl vastag a szakállunk, így a legtöbbet fogjuk használni egyszerű típusok programokat. Aki szeretne, bemehet a programozás számtalan gazdagságának völgyébe, de itt minden egyszerű - a program kifejezésekből áll, viszont egyszerű függvényekből áll némi aritással, változókkal és konstansokkal. Minden kifejezés egyet számol a program által visszaadott értékek közül.
Például: néhány egyedi programnégyzet két kifejezésből áll, és megpróbál (nem túl sikeresen) megoldani egy másodfokú egyenletet:
függvény négyzet(a, b, c)(x1 = min(sin(b)*(a+1), 0); x2 = 3 + exp(log(b*a)); return (x1, x2); )
A bemutató mellett döntöttünk, most a tárhelyet kell rendezni. Mivel még mindig nagyon sok tánc van e programok körül, beleértve a rendszer egyik részéből a másikba való áthelyezésüket (amelyek általában az én esetemben általában különböző nyelvek), akkor a mintánkat fa formában tárolni nem túl kényelmes. Többet képviselni kényelmes módon(ideális esetben valamilyen véges ábécé feletti karakterláncok halmaza) az egyéni program-fák_készletének meg kell tanulnia kódolni/dekódolni.
Itt n, +, *, if függvények; 2 - állandó; a és b változók. BAN BEN valódi problémákat súlytáblázat, ilyen halmazzal nem lehet másodfokú egyenletet megoldani. Szem előtt kell tartania azt a tényt is, hogy a nullával való osztás és más apokalipszis forgatókönyvek elkerülése érdekében minden függvényt a valós számok teljes halmazán kell definiálni (jól, vagy a feladatban használt bármely halmazon). Ellenkező esetben őrködni kell, nulláról logaritmusokat fogni, majd kitalálni, hogy mit csináljunk vele. Nem vagyunk büszke emberek, a könnyebb utat választjuk, kizárva az ilyen lehetőségeket.
Tehát egy ilyen tábla segítségével nem okoz gondot a függvények fától sorra és visszafuttatása. Például a következő sort kaptuk a dekódoláshoz:
A táblázat segítségével azonosítjuk az egyes elemeket, és emlékezünk az aritásra is:
Most az arity segítségével hivatkozásokat helyezünk el a függvény argumentumaira:
Felhívjuk figyelmét, hogy a lista utolsó 3 eleme senkinek nem volt haszna, és értékeik semmilyen módon nem befolyásolják a függvény eredményét. Ez annak köszönhető, hogy az érintett listaelemek száma, a fa csomópontjainak száma állandóan lebeg az aritásuk függvényében. Tehát jobb tartalékokat felhalmozni, mint később egy nem megfelelő fával szenvedni.
Ha most az első elemnél fogva felhúzzuk, akkor a kifejezésfa a kezünkben lóg:
A függvény értéke a fán való rekurzív bejárással számítható ki:
A fa keresztezése véletlenszerűen kiválasztott ágak cseréje. A keresztező karakterláncokat többféleképpen is meg lehet valósítani: egypontos rekombináció (darabonkénti ragasztás), kétpontos rekombináció, elemenkénti csere, stb. Hosszú összetett mondatokkal írhatók le részvételi kifejezések, de elég egy pillantás a diagramra, hogy megértsük, mi az:
Csak annyit kell megjegyezni, hogy a rekombinációban a ragasztási helyek véletlenszerűen kerülnek kiválasztásra, csakúgy, mint az elemenkénti keresztezésnél, a csere bizonyos valószínűséggel megtörténik. A fákkal való keresztezés az öröklődés szempontjából ígéretesebbnek tűnik, de nehezebb megvalósítani.
Az egyének generációkra oszlanak. Az új generáció az előző generáció egyedeinek gyermekeiből áll. Kiderült, hogy létezik a fiúk és lányok jelenlegi generációja, az apák és anyák generációja, a nagyszülők, a dédmamák, és így tovább a nulladik generációig - mindennek az ősei büszke emberek. A születés után egy új nemzedék minden egyede megpróbál megoldani egy problémát, cselekedeteit valamilyen isteni erőnléti függvény értékeli, és az ifjúság aktivitásának megítélésétől függően az egyén kap némi esélyt az utódnemzedésre, vagyis az osztályba kerülésre. a nemzésre kiválasztott generáció legjobb képviselői közül. Világunk kemény és kegyetlen, és a disztópiák minden kánonja szerint (vagy a Führer elképzelései szerint, ahogy akarod) a haszontalan nyugdíjas szülők, miután teljesítették küldetésüket, hogy utódokat szüljenek, kirándulnak gázszállító furgon, életteret szabadítva fel pár gyerekük számára. A gyerekek szüleik nyomdokaiba lépnek, és így tovább nemzedékről nemzedékre.
Ugyanazon fitneszfunkciónak (vagy fitneszfunkciónak), amely a párzási kvótákat adja ki, megfelelően fel kell mérnie az egyén képességét a probléma és probléma megoldására. numerikus kifejezés ez az alkalmasság (minél magasabb az érték, annál jobb az alkalmasság). Például ugyanazon másodfokú egyenlet esetében ez annak a mértéke lehet, hogy az egyenlet bal oldalának értéke mennyire közelít a nullához, ha x1, x2 értékeket helyettesítünk, az egyedi program által kiszámítva.
A fitnesz funkció a generáció minden egyedének megad egy bizonyos számot, amely jelzi a hasznosságát és alkalmasságát. Ez az érték befolyásolja a kiválasztási eljárást: minél magasabb egy egyén értéke, annál valószínűbb, hogy talál párat a keresztezéshez (és akár egynél többet is). A gyakorlatban egy generáció összes egyedére vonatkozó alkalmasság kiszámítása után ezeket az értékeket normalizáljuk (úgy, hogy az egyedek fittségének összege 1 legyen), és minden csókolóhelyre sorsot vetünk ( véletlen szám 0-tól 1-ig), meghatározva a szerencsés személyt. Az alfahím szerezhet magának néhány helyet, a vesztes nem kap semmit, és egyedül marad egy kopott 1994-es naptárral Pamellával. Ezt a kiválasztási módszert „rulettválasztásnak” nevezik, és sematikusan így néz ki:
Vannak más kiválasztási módszerek is, de mindegyik betartja Általános szabály: Minél nagyobb az egyén edzettsége, annál inkább részt kell vennie a keresztezésben. Az elitizmus opciót is bevonhatja a folyamatba, amikor legjobb képviselője generációs díjat kap a Hazáért végzett szolgálatokért további évekélet: változtatás nélkül száll át a következő nemzedékre, bár egyidejűleg gyermeket is szülhet. Ez lehetővé teszi, hogy ne veszítsünk sokat jó döntés, amely az átkelés során megsemmisülhet.
Itt említsük meg a mutációt is. Ez egy művelet véletlenszerűen kis valószínűséggel megváltoztatja az egyed egy töredékét, ami lehetővé teszi a génállomány diverzifikálását. Hasznos dolog, hirtelen egy ilyen mutáció segít lebontani a laktózt! És ha nem, és van még egy kéz, akkor a hátralévő napjaiban szenvednie kell vele, még mindig kevés az esélye, hogy utódokat szüljön.
Világunk addig létezik, amíg szükségünk van rá. Vagy beállítjuk a minket kielégítő edzettségi szintet, és amikor egy kellően menő egyed megjelenik, leállítjuk a folyamatot, vagy megnézzük, hogy a generáció egyedei mennyiben térnek el egymástól. Logikus, hogy ha az egész nemzedék egypetéjű ikrekből áll, akkor a további párosítás nem ad semmi újat a génállománynak, és naivitás egyetlen mutációban reménykedni. Időkorlátot is beállíthat.
Megtanuljuk egy probléma megoldását egyéni genetikai algoritmus formájában ábrázolni - egy rögzített hosszúságú lista valamilyen ábécé alapján. Ezt követően kiválasztunk egy fitneszfüggvényt, amely képes kiértékelni az egyéneket, és véletlenszerűen nulla generációt generál. Itt kezdődik a szabad szerelem körforgása: kiszámítják egy nemzedék egyedeinek alkalmasságát, ezek alapján párok alakulnak ki (a veszteseket kidobják, és az alfahímek nem korlátozódnak egy párra), a megmaradtak párosodnak, szülnek. pár gyerek (akikhez mutáció is kapcsolódik) és öngyilkos lesz. Ez így megy egészen addig, amíg meg nem találjuk a kiválasztottat, vagy a változások már nem tetszenek nekünk, vagy belefáradunk az egészbe. Nos, hogyan bírom diagram nélkül:
A következő feladat előtt állunk: fejlesztés genetikai algoritmus segítségével automatizált rendszerek tankbot irányítása. A robotot automatikusan kell létrehozni és módosítani, pl. fejlődése során 1 az 1 ellen csatákban „alkalmazkodni” egy adott és előre kiválasztott ellenfélhez.
Nyilvánvaló, hogy a sikeres harchoz ezeket a műveleteket nem kaotikusan kell végrehajtani, hanem a csatatéren uralkodó helyzettől (állapottól): a tankok helyzetétől, sebességétől, energiájától és egyéb paramétereitől függenek. Így a tank irányításának folyamata a fenti műveletek végrehajtásához vezet a csata állapota alapján. Azt a törvényt, amely a harctéri helyzet alapján meghatározza a harckocsi viselkedését (cselekvését), irányító funkciónak nevezzük, és ez lesz a genetikai algoritmusunk egyede.
Mivel a vezérlő funkciónak 4 értéket kell visszaadnia (lövési energiát, torony elfordulási szögét, hajótest elfordulási szögét, tank mozgását), így az utolsó részben leírtak szerint négy kifejezésből fog állni, pl. négy sorból/fából.
A kódolási táblázat összeállításához el kell döntenie az alapvető függvények, változók és állandók halmazáról.
Funkciók:
+(x, y) = x + y
++(x, y, z) = x + y + z
n(x) = -x
*(x, y) = x * y
**(x, y) = x * y * z
min(x, y) = x > y? y:x
s(x) = 1/(1+exp(-x))
if(x, y, z, w) = x > y? z:w
Változók:
x, y - az ellenfél tankjának koordinátái a tankunkhoz képest;
dr az a távolság, amely még hátra van, amíg a tankunk „eléri”;
tr az a szög, amelyben a tartályunk még elfordul;
w a tartályunk és a mező széle közötti távolság;
dh az ellenséges harckocsi iránya és a tankunk lövege közötti szög;
GH a harckocsink fegyverének forgásszöge;
h - az ellenfél tankjának mozgási iránya;
d a tankunk és az ellenfél tankja közötti távolság;
e az ellenfél tankjának energiája;
E a tartályunk energiája.
Nos, konstansok: 0,5, 0, 1, 2, 10
Általánosságban elmondható, hogy az egyén alkalmasságának kiszámítása egy harcsorozat lebonyolítását jelenti! Azok. Egy ilyen jelentéktelennek tűnő pont, mint a fitnesz téves számítása, az ilyen tamburával való táncokból áll:
1) Rendszerünk elmenti az egyed kódolt kromoszómáit a chromosome.dat fájlba;
2) Mindenki számára elindul a „Robocode” környezet, amely párbajt szervez. Egy .battle formátumú fájllal látjuk el, amely leírja a csata körülményeit - a harckocsik listája, a mező mérete, a körök száma stb.;
3) A harchoz a Robocode tankokat tölt be, a shell robotunk beolvassa a chromosome.dat fájlt kódolt viselkedéssel, akciók sorozatává értelmezi és ezek szerint vezeti le a csatát;
4) A küzdelem végén a Robocode környezet beírja a csata eredményét a results.txt fájlba, és befejezi a munkáját;
5) Rendszerünk kiválasztja ezt a fájlt, elemzi, és kivonja belőle a tankunk és az ellenfél összpontszámát. Egyszerű aritmetikával megkapjuk az alkalmassági értéket.
A genetikai algoritmus megvalósítása során a populáció egyedszámát 51-re (25 pár + egy elit egyed) választottuk. Az evolúció egy lépése (népességváltozás) körülbelül egy tucat percet vesz igénybe, így összességében több órán keresztül elhúzódik az ügy.
Ennek eredményeként bemutatjuk a Walls és a Crazy robotok riválisának létrehozásának eredményeit:
Az első esetben leállítottuk a folyamatot, miután az egyik egyed elérte a 70-es edzettségi szintet, nekünk elég volt, ha az egyedek átlagos edzettsége egy generációban meghaladta az 50-et.
Az egyik feladat intelligens rendszerek az optimális megoldás keresése: amikor a rendszert számos külső és belső tényezők, az intelligens eszköznek mindet figyelembe kell vennie, és az előnye szempontjából optimális viselkedést kell választania. Tegyük fel, hogy ha Ön egy raktár tulajdonosa, számos tényezőt kell figyelembe vennie (áruegységek költsége, kereslet, különféle áruk raktárban való tárolásának költségei stb.), hogy minimalizálja a költségeket és a legnagyobb profitot érje el.
Egy másik példa: csúszós úton haladsz, és az autója hirtelen csúszásba kezd, néhány méterrel tőle jobb oldalon van egy oszlop, és egy teherautó halad a szembejövő sávban. Figyelem a kérdésre: hogyan lehet kikerülni a helyzetből a legkevesebb veszteséggel, vagy ami még jobb, ezek nélkül. Sok tényezőt kell figyelembe venni: a sebességed és a szembejövő autó sebessége, az oszloptól való távolság, a csúszás „meredeksége” stb. Mit kell csinálnunk? Adja meg a gázt, próbáljon kijutni a csúszásból, vagy fékezzen, esetleg próbáljon meg óvatosan az árokba csúszni, hogy ne ütközzen oszlopnak. Számos lehetőség létezik, és az optimális kiválasztásához mindegyiket ki kell próbálnia. Legyen számítógépes játék- menthetsz és játszhatsz addig, amíg az eredmény meg nem felel. Ez az optimális megoldás keresése.
A rendszerekben mesterséges intelligencia ilyen problémák megoldására használják.
Genetikai algoritmusok– adaptív keresési módszerek, amelyeket funkcionális optimalizálási problémák megoldására használnak. Az evolúció mechanizmusain és modelljein, valamint biológiai algoritmusok genetikai folyamatain alapulnak.
Leegyszerűsítve: lényegében a genetikai algoritmus egy olyan módszer, amely megoldásokat számlál olyan problémákra, amelyekre nem lehet megoldást találni. matematikai képletek. Egy összetett többdimenziós probléma megoldásainak egyszerű felsorolása azonban végtelenül hosszú időt vesz igénybe. Ezért a genetikai algoritmus nem minden megoldást keres, hanem csak a legjobbakat. Az algoritmus felvesz egy csoport megoldást, és megkeresi közöttük a legmegfelelőbbet. Aztán kicsit megváltoztatja őket - új megoldásokat kap, amelyek közül ismét kiválasztja a legjobbat, és elveti a legrosszabbat. Így az algoritmus a munka minden lépésében kiválasztja a legmegfelelőbb megoldásokat (kiválasztást végez), hisz azok a következő lépésben még több eredményt adnak. legjobb megoldások(fejlődik).
Amint már érted, a genetikai algoritmusok elméletében analógia van a feladat és a feladat között biológiai folyamat. Innen a terminológia...
Egyedi– egy megoldás a problémára.
Népesség— egy probléma megoldásának összessége. Az algoritmus elején véletlenszerűen generálunk egy megoldáshalmazt (kezdeti sokaságot). Ezek a megoldások egyre jobbak lesznek (fejlődnek), ahogy az algoritmus addig működik, amíg eleget nem tesznek a probléma feltételeinek.
És azonnal a legegyszerűbb klasszikus példa. Tegyük fel, hogy a robotnak hat ellenőrzőpontot kell megkerülnie legkevesebb időt. Az egyes pontok közötti távolság távolságmátrixként van megadva.
Ez az utazó értékesítő (utazó) probléma egy változata - az NP-teljes osztályba tartozik, vagyis nem oldható meg matematikai képletekkel.
A probléma megoldása a vezérlőpontok átadásának sorozata. Vegyünk néhányat lehetséges megoldások(magánszemélyek) – ez az.
Fitness funkció– egy populáció egyedeinek minőségét meghatározó funkció. Példánkban ez lesz a kiválasztott útvonalon a pontok közötti távolságok összege.
FP = P(1)+P(2)+P(3)+P(4)+P(5)+P(6),
ahol P(1) ... P(6) a távolság mátrixból való megfelelő átmenet pontjai közötti távolság
Meg kell tehát találnunk a minimális távolságot, mint kisebb érték FP az egyén számára, annál jobb.
Számítsuk ki a fitnesz függvényeket. Az első személynek:
A fennmaradó egyedeknél ugyanígy kapunk.
Körülbelül négy éve, az egyetemen hallottam egy optimalizálási módszerről, amit genetikai algoritmusnak neveznek. Pontosan két dolgot jelentettek róla mindenhol: menő és nem dolgozik. Illetve működik, de lassú, megbízhatatlan, és nem szabad sehol használni. De szépen be tudja mutatni az evolúció mechanizmusait. Ebben a cikkben megmutatom gyönyörű módon nézze meg élőben az evolúció folyamatait ennek munkájának példáján egyszerű módszer. Csak egy kis matematikára, programozásra és némi képzelőerőre van szüksége.
A módszer lényege, hogy moduláljuk az evolúciós folyamatot: van valamiféle populációnk (vektorkészletünk), amely szaporodik, amelyre hatással vannak a mutációk és a természetes szelekció a minimalizálás alapján történik. objektív funkció. Nézzük meg közelebbről ezeket a folyamatokat.
Tehát először is lakosságunknak kell szaporodnak. A szaporodás alapelve, hogy az utód hasonlít a szüleire. Azok. definiálnunk kell valamiféle öröklődési mechanizmust. És jobb lesz, ha benne van a véletlen eleme is. De az ilyen rendszerek fejlődési üteme nagyon alacsony - a genetikai sokféleség csökken, a populáció degenerálódik. Azok. a függvény értéke megszűnik minimalizálni.
A probléma megoldására egy mechanizmust vezettek be mutációk, amely egyes egyedeknél véletlenszerű változásokból áll. Ez a mechanizmus lehetővé teszi, hogy valami újat vigyünk be a genetikai sokféleségbe.
A következő fontos mechanizmus az kiválasztás. Mint elhangzott, a szelekció olyan egyedek kiválasztása (esetleg a most születettek közül, vagy mindegyikből - a gyakorlat azt mutatja, hogy ez nem játszik döntő szerepet), amelyek jobban minimalizálják a funkciót. Általában annyi egyedet választanak ki, ahány a szaporodás előtt volt, így korszakról korszakra állandó mennyiség egyedek egy populációban. Szokásos a „szerencséseket” is kiválasztani - bizonyos számú egyedet, akik esetleg nem minimalizálják jól a funkciót, de sokszínűséget vezetnek be a következő generációkban.
Ez a három mechanizmus legtöbbször nem elegendő a funkció minimalizálásához. Így degenerálódik a népesség - a helyi minimum előbb-utóbb az egész lakosságot elnyomja értékével. Amikor ez megtörténik, az ún felráz(az analógiák természetében - globális katasztrófák), amikor szinte a teljes populáció elpusztul, és új (véletlen) egyedek jönnek létre.
Itt található a klasszikus genetikai algoritmus leírása, könnyen megvalósítható, és van hely a képzeletnek és a kutatásnak.
Matematikai szempontból az ilyen optimalizálás puszta apróság. Egy ilyen függvény grafikonja egy hatalmas többdimenziós „lyuk” (mint az ábrán egy háromdimenziós parabaloid), amelybe óhatatlanul belecsúszik, ha követi a gradienst. Az egyetlen lokális minimum a globális. .
A probléma csak az, hogy már a minimumhoz közelítve jelentősen lecsökken azoknak az utaknak a száma, amelyeken le lehet menni, és összesen annyi irányunk van, ahány dimenzió (azaz a pixelek száma). Nyilvánvalóan nem érdemes genetikai algoritmussal megoldani ezt a problémát, de érdekes folyamatokat tekinthetünk meg populációnkban.
A kezdeti képeknek a nonogrammokat („japán szkennelőszavak”) vettem, de őszintén szólva, lehet csak fekete négyzeteket venni - nincs különbség. Az alábbiakban több kép eredményét láthatjuk. Itt a „házon” kívül mindenkinél egyedenként átlagosan 100 volt a mutációk száma, 100 egyed volt a populációban, a szaporodás során a populáció 4-szeresére nőtt. Minden korszakban 30% volt a szerencsés. A házhoz kisebb értékeket választottak (30 egyed a populációban, egyedenként 50 mutáció).
Kísérletileg megállapítottam, hogy a „szerencsések” használata a szelekcióban csökkenti a populáció minimálisra hajlamosságát, de segít kilábalni a stagnálásból – a „szerencsések” nélkül a stagnálás állandó lesz. Ami a grafikonokon látszik: a bal oldali grafikon a „fáraó” populáció alakulását mutatja szerencsésekkel, a jobb oldali szerencsések nélküli.
Így azt látjuk, hogy ez az algoritmus lehetővé teszi a probléma megoldását, bár nagyon hosszú ideje. Túl sok nagyszámú rázkódás, nagy képek esetén megoldható nagy mennyiség egyedek egy populációban. A különböző dimenziókhoz tartozó paraméterek optimális kiválasztását a bejegyzés keretein kívül hagyom.
De van több is érdekes megoldás adott probléma: megérthetjük, hogy egy lokális minimumba csúsztunk, erős felrázást hajtunk végre (vagy akár újra kezdeményezünk egyéneket), majd az ismert minimumhoz közeledve büntetéseket adunk hozzá. Mint látható, a képek váltakoznak. Felhívjuk figyelmét, hogy nincs jogunk hozzányúlni eredeti funkciója. De emlékezhetünk a helyi minimumokra, és magunk is büntethetünk.
Ezen a képen az az eredmény látható, amikor egy lokális minimum (erős stagnálás) elérésekor a populáció egyszerűen kihal.
Itt a populáció kihal, és egy kis büntetést adnak hozzá (ami megegyezik a normál távolsággal egy ismert minimumhoz képest). Ez nagymértékben csökkenti az ismétlések valószínűségét.
Érdekesebb, ha a populáció nem hal ki, hanem egyszerűen elkezd alkalmazkodni az új feltételekhez (következő ábra). Ez 0,000001 * összeg ^ 4 büntetéssel érhető el. Ebben az esetben az új képek kissé zajosak lesznek:
Ezt a zajt a büntetés max(0,000001 * összeg ^ 4, 20) értékre való korlátozásával küszöböljük ki. De látjuk, hogy a negyedik lokális minimumot (dinoszauruszt) nem lehet elérni – valószínűleg azért, mert túl közel van valamelyik másikhoz.
Milyen következtetéseket vonhatunk le – merjem ki – a modellezésből? Először is látjuk szexuális szaporodás- a fejlődés és az alkalmazkodóképesség legfontosabb motorja. De ez önmagában nem elég. A véletlenszerű, apró változtatások szerepe rendkívül fontos. Ők biztosítják az evolúció során új állatfajok megjelenését, hazánkban pedig a populáció sokszínűségét.
A Föld evolúciójában a legfontosabb szerepet az játszotta a természeti katasztrófákés tömeges kihalások (dinoszauruszok, rovarok stb. kihalása – körülbelül tíz fő volt – lásd az alábbi ábrát). Ezt szimulációnk is megerősítette. A „szerencsések” kiválasztása pedig ezt mutatta leginkább gyenge organizmusok napjaink a jövőben a következő generációk alapjává válhatnak.
Ahogy mondják, minden olyan, mint az életben. Ez a „csináld magad” evolúciós módszer világosan mutatja érdekes mechanizmusokés szerepük a fejlődésben. Természetesen van még sok érdemesebb evolúciós modell (természetesen a difúrokon alapuló), több, az élethez közelebb álló tényezőt figyelembe véve. Természetesen több is van hatékony módszerek optimalizálás.
Forrás
függvény res = genetikai(fájl) %generáló globális A B; im2line(fájl); dim = hossz(A(1,:)); szám = 100; reprod = 4; mut = 100; kiválasztás = 0,7; stagnálás = 0,8; pop = round(rand(count,dim)); res = ; B = ; localmin = ; localcount = ; k = 1:300 %reprodukció esetén j = 1:count * reprod pop = ; vége %mutáció idx = 10 * (hossz(res) > 5 && std(res(1:5)) == 0) + 1; for j = 1:count * mut a = floor(rand() * count) + 1; b = padló(rand() * dim) + 1; pop(a,b) = ~pop(a,b); vége %kiválasztás val = func(pop); érték(1:count) = érték(1:count) * 10; npop = nullák(count,dim); = sort(érték); res = ; opt = pop(i(1),:); fn = sprintf("eredmény/%05d-%d.png",k,s(1)); line2im(opt*255,fn); if (s(1) == 0 || localcount > 10) localmin = ; localcount = ; B = ; % pop = round(rand(count,dim)); folytatni;
% szünet;
end for j = 1:floor(count * select) npop(j,:) = pop(i(j),:); end %adad luckers for j = (floor(count*select)+1) : count npop(j,:) = pop(floor(rand() * count) + 1,:); vége %fixing stagnálás if (length(res) > 5 && std(res(1:5)) == 0) if (localmin == res(1)) localcount = localcount+1; egyébként helyi szám = 1; end localmin = res(1); for j = 1:count*stagn a = floor(rand() * count) + 1; npop(a,:) = crossingover(npop(a,:),rand(1,dim)); end end pop = npop; vége res = res(hossz(res):-1:1); vége függvény res = crossingover(a, b) x = round(rand(size(a))); res = a .* x + b .* (~x); vége függvény res = func(v) globális A B; res = inf; ha i = 1:méret(A,1) res = min(res,sum(v ~= A(i,:),2)); vége i = 1 esetén:méret(B,1) res = res + max(0,000001 * sum(v == B(i,:),2) .^ 4,20); end end function = im2line(files) global A sz; A = ; fájlok = cellstr(fájlok); for i = 1:size(files,1) imorig = imread(char(files(i,:))); sz = méret(imorig); A = )]; vége A = A / 255; vége függvény = line2im(im,file) global sz; imwrite(reshape(im*255,sz),file); vége Címkék: Címkék hozzáadása BAN BEN Utóbbi időben Egyre több szó esik újszerű algoritmusokról, mint pl
neurális hálózatok
Szomorú, mert az utódok átlagos edzettsége 38,8-nak bizonyult, a szülőknél ez az együttható 59,4. Ebben a pillanatban célszerűbb egy mutációt használni, egy vagy több értéket 1 és 30 közötti véletlen számmal helyettesítünk.
Az algoritmus a túlélési arány eléréséig működik egyenlő nullával. Azok. megoldása lesz az egyenletnek.
Rendszerek nagyobb népesség(például 50 helyett 5, és gyorsabban és stabilabban konvergál a kívánt szintre (0).
Ezután az egyenlet megoldásához hívjuk meg a Solve() függvényt, amely visszaadja a megoldást tartalmazó allélt. Hívja a GetGene() parancsot, hogy megkapja a gént a megfelelő a, b, c, d értékekkel. Az ezt az osztályt használó szabványos main.cpp eljárás így nézhet ki:
#include "
Maga a CDiofantin osztály:
#beleértve A cikk a Wikipédia és a weboldal anyagain alapul
A genetikai algoritmusok (GA-k) ötlete meglehetősen régen (1950-1975) jelent meg, de igazán csak az utóbbi évtizedekben váltak kutatás tárgyává. Ezen a területen az úttörőnek D. Hollandot tartják, aki sokat kölcsönzött a genetikából, és számítógépekhez adaptálta. A GA-kat széles körben használják mesterséges intelligencia rendszerekben, neurális hálózatokban és optimalizálási problémákban.
A genetikai algoritmusok modelljei a természet evolúciója és véletlenszerű keresési módszerek alapján készültek. Ebben az esetben a véletlenszerű keresés az evolúció legegyszerűbb funkciójának megvalósítása - a véletlenszerű mutációk és az azt követő szelekció.
Matematikai szempontból az evolúciós keresés nem jelent mást, mint egy létező véges megoldáshalmaz átalakulását újjá. A folyamatért felelős funkció a genetikai keresés. A fő különbség egy ilyen algoritmus és a véletlenszerű keresés között az iterációk (ismétlések) során felhalmozott információk aktív felhasználása.
A GA-k a következő célokat követik:
Jelenleg a genetikai algoritmusok és módosított változataik lényege a hatékony megoldások keresése, az eredmény minőségének figyelembevételével. Más szóval, a legjobb egyensúly megtalálása a teljesítmény és a pontosság között. Ez a „legrátermettebb egyén túlélése” jól ismert paradigmája miatt következik be bizonytalan és tisztázatlan körülmények között.
Soroljuk fel a fő különbségeket a GA és a legtöbb egyéb módszer között az optimális megoldás megtalálásához.
A genetikai algoritmusok két feltétel alapján végeznek számításokat:
Ha ezen feltételek valamelyike teljesül, a genetikai algoritmus leállítja a további iterációk végrehajtását. Ezenkívül a megoldási tér különböző régióiból származó GA-k használata lehetővé teszi számukra, hogy sokkal jobban találjanak olyan új megoldásokat, amelyek megfelelőbb célfüggvény-értékekkel rendelkeznek.
Tekintettel arra, hogy a GA-k genetikán alapulnak, a terminológia nagy része ennek felel meg. Bármely genetikai algoritmus a kezdeti információk alapján működik. A kezdeti értékek halmaza a Pt = (n1, n2, ..., nn) sokaság, ahol pi = (r1, ..., rv). Nézzük meg közelebbről:
Mit jelent a „kódolt” a GA kontextusában? Általában minden érték valamilyen ábécé alapján van kódolva. A legegyszerűbb példa a számok átalakítása decimális számrendszerből bináris ábrázolásra. Így az ábécé halmazként (0, 1) van ábrázolva, és az 15710-es számot az 100111012 kromoszóma fogja kódolni, amely nyolc génből áll.
A szülők olyan elemek, amelyeket egy adott feltételnek megfelelően választanak ki. Például gyakran ilyen feltétel a véletlenszerűség. A kiválasztott elemek a keresztezés és mutáció műveletei révén újakat generálnak, amelyeket leszármazottaknak nevezünk. Így a genetikai algoritmus egy iterációjának végrehajtása során a szülők új generációt hoznak létre.
Végül, az evolúció ebben az összefüggésben generációk váltakozása lesz, amelyek mindegyike más-más kromoszómakészlettel rendelkezik a jobb fittség, vagyis az adott feltételeknek való megfelelőbb megfelelés érdekében. Az evolúció folyamatában az általános genetikai hátteret genotípusnak, az élőlény és a külső környezet közötti kapcsolat kialakulását pedig fenotípusnak nevezzük.
A genetikai algoritmus varázsa a fitnesz függvényben rejlik. Minden egyénnek megvan a maga jelentése, amely az adaptációs függvényen keresztül tudható meg. Fő feladata, hogy ezeket az értékeket értékelje a különböző alternatív megoldásokhoz, és válassza ki a legjobbat. Más szóval, a legalkalmasabb.
Az optimalizálási feladatokban a fitneszfüggvényt célfüggvénynek, a vezérléselméletben hibának, a játékelméletben költségfüggvénynek, stb.
Végső soron arra a következtetésre juthatunk, hogy a genetikai algoritmusok egyedek, organizmusok vagy kromoszómák populációját elemzik, amelyek mindegyikét gének kombinációja (néhány érték halmaza) képviseli, és optimális megoldást keresnek a populáció egyedeinek átalakításával. közöttük a mesterséges evolúció.
Az egyes elemek egyik vagy másik irányú eltérései általában összhangban vannak a mennyiségek normális eloszlási törvényével. A GA ugyanakkor biztosítja azon tulajdonságok öröklődését, amelyek közül a leginkább alkalmazkodó fix, ezáltal jobb populációt biztosít.
Bontsuk le lépésről lépésre a legegyszerűbb (klasszikus) GA-t.
Nézzük meg röviden az algoritmus kevésbé nyilvánvaló részeit. A munkaviszony megszüntetésének két feltétele lehet:
A genetikai operátorok a mutációs operátor és a keresztező operátor. A mutáció bizonyos valószínűséggel véletlenszerű géneket változtat meg. Jellemzően a mutáció valószínűsége alacsony számértékkel rendelkezik. Beszéljünk részletesebben a genetikai algoritmus „keresztező” eljárásáról. Ez a következő elv szerint történik:
Oldjuk meg a problémát egy genetikai algoritmus segítségével, a maximális egységszámú egyed keresésének példájával. Álljon egy egyed 10 génből. Állítsunk be egy nyolc egyedből álló elsődleges populációt. Nyilvánvalóan a legjobb személynek a 1111111111-esnek kell lennie. Hozzunk létre egy GA-t a megoldáshoz.
A táblázatból kitűnik, hogy a 3. és 7. egyedek a legnagyobb egységszámmal rendelkeznek, így a populáció legalkalmasabb tagjai a probléma megoldására. Mivel jelenleg nincs megfelelő minőségű megoldás, az algoritmus továbbra is működik. El kell végezni az egyének kiválasztását. Az egyszerűbb magyarázat kedvéért a kiválasztás véletlenszerűen történjen, és egy mintát kapunk az egyedekből (n7, n3, n1, n7, n3, n7, n4, n2) - ezek az új populáció szülei.
A további intézkedések nyilvánvalóak. A GA-kkal kapcsolatban a legérdekesebb dolog az egyes populációk átlagos egységszámának becslése. Az első populációban átlagosan 5,375 egység volt egyedenként, a leszármazottak populációjában - 6,25 egység egyedenként. És ez a tulajdonság akkor is megfigyelhető, ha a mutációk és keresztezések során az első populációban a legtöbb egyedszámmal rendelkező egyed elveszik.
A genetikai algoritmus elkészítése meglehetősen összetett feladat. Először lépések formájában felsoroljuk a tervet, majd mindegyiket részletesebben elemezzük.
Az első szakasz kimondja, hogy az ábécé, amelybe egy megoldáshalmaz vagy egy sokaság minden elemét kódolják, kellően rugalmasnak kell lennie ahhoz, hogy egyszerre lehetővé tegye a véletlenszerű permutációk szükséges műveleteit és értékelje az elsődleges és az átment elemek alkalmasságát. változtatások. Matematikailag megállapították, hogy ideális ábécét ezekre a célokra nem lehet létrehozni, ezért ennek összeállítása az egyik legnehezebb és legkritikusabb szakasz a GA stabil működésének biztosításához.
Nem kevésbé nehéz a módosítási és létrehozási operátorok meghatározása. Sok operátor képes elvégezni a szükséges műveleteket. Például a biológiából ismert, hogy minden faj kétféleképpen szaporodhat: ivarosan (keresztezés) és ivartalanul (mutációk). Az első esetben a szülők genetikai anyagot cserélnek, a másodikban a szervezet belső mechanizmusai és a külső hatások által meghatározott mutációk fordulnak elő. Emellett a természetben nem létező reprodukciós modellek is használhatók. Például használja három vagy több szülő génjeit. A keresztezéshez hasonlóan sokféle mechanizmus beépíthető a genetikai mutációs algoritmusba.
A túlélés módszerének megválasztása rendkívül megtévesztő lehet. A genetikai algoritmusban számos módszer létezik a szelekcióra. És amint azt a gyakorlat mutatja, a „legrátermettebb túlélése” szabály nem mindig a legjobb. Bonyolult technikai problémák megoldása során gyakran kiderül, hogy sok átlagos vagy még rosszabb megoldás közül kerül ki a legjobb megoldás. Ezért gyakran elterjedt a valószínűségi megközelítés alkalmazása, amely azt állítja, hogy a legjobb megoldásnak nagyobb az esélye a túlélésre.
Az utolsó szakasz olyan rugalmasságot biztosít az algoritmus számára, amellyel senki más nem rendelkezik. A megoldások elsődleges populációja beállítható bármely ismert adat alapján, vagy teljesen véletlenszerűen úgy, hogy egyszerűen átrendezi a géneket az egyedeken belül, és véletlenszerű egyedeket hoz létre. Azonban mindig érdemes megjegyezni, hogy az algoritmus hatékonysága nagymértékben függ a kezdeti sokaságtól.
Egy genetikai algoritmus hatékonysága teljes mértékben a tervben leírt lépések helyes végrehajtásától függ. Itt különösen nagy hatást gyakorol az elsődleges populáció létrehozása. Ennek számos megközelítése létezik. Leírunk néhányat:
Ebből arra következtethetünk, hogy a genetikai algoritmusok hatékonysága nagymértékben függ a programozó e téren szerzett tapasztalatától. Ez a genetikai algoritmusok hátránya és előnye is.