Kiire näide geneetilisest arengust JavaScriptis: teeme lapse.

"Mutatsiooniprotsess on geneetilise varieeruvuse ja seega ka evolutsiooni uute materjalide ainus teadaolev allikas." - Dobzhansky, 1957.

Geneetilise evolutsiooni algoritmid on minu jaoks tõeliselt põnevad. Võimalus virtuaalset DNA-d programmeerida on lihtsalt infotehnoloogia fenomenaalne feat. Võimalus kirjutada koodina Darwini evolutsiooniteooriat ja näha tegelikkuses Fittesti mudeli ellujäämist on lihtsalt jahmatav.

Ma pole kunagi varem geneetilisi algoritme puutunud ja otsustasin, et on aeg alustada. Ja mis oleks parem koht alustamiseks kui tegelik, algus, eks? Selles õpetuses loon „kepi“ ja see kepp tahab jõuda „ringi“. Sellest järeldage, mida saate, aga ma kirjutan peresõbralikke õpetusi ja see jääb selliseks.

Selle inspiratsiooniks on mul The Coding Train: Coding Challenge # 29 uskumatult suur mõju. Selle link siin. Teda inspireerisid nutikad raketid, nii et kuigi ma ei tee midagi uut ega originaalset, loodan, et see on geneetilise evolutsiooni algoritmi näide. Kasutan P5.JS teeki, mille võtaksin kokku visuaalse JavaScripti teegina.

Enne igasuguse geneetilise algoritmi loomist tuleb kõigepealt seadistada tegelik säte. Esiteks loon väga lihtsa HTML-lehe.

Mul on P5 jaoks kaks raamatukogu. Peamine tegeleb ekraanile joonistamise, muutujate kiirendamisega jne. Kepp on joon, mis areneb, populatsioon on pulkade kogu ja dna on see, mida ma peaksin pidama geneetilise algoritmi tuumaks. Vaatame Sticki koodi:

Nii et kepil on mõned põhifunktsioonid. See peab olema võimeline liikuma, nii et kiiruse, kiirenduse ja asukoha muutujates on liikumise mootor (parema termini nõudmiseks). Praegu kontrollib kogu liikumist salapärane DNA funktsioon. Enne kui jõuame DNA juurde, vaatame üle elanikkonna:

Rahvastik pole tegelikult nii huvitav. See loob 25 pulka, mis minu arvates on elanikkonna jaoks piisav, ja liigutab need seejärel ekraanil. Selle funktsiooniga ei tohi takistusi murda! DNA:

Sel hetkel ei tee DNA põhimõtteliselt midagi. Ühest pulgast saab ühe DNA ja ühel DNA-l on 200 geeni komplekt, mis on minu väikese pulga eluea pikkus. Ärge muretsege, õigel ajal lisandub veel. Põhifail:

Nii et Main teeb siin mõned õiglased asjad. Esiteks peame looma uue keppide põlvkonna, mis kujutab endast rahvaarvu kiirendamist, ja siis loome oma ringi, mille järgi kepid hiljem suunata tahavad. Siis joonistame kõik ekraanile, millele on lisatud võimalus tappa ja luua uus põlvkond, iga kord, kui nende elutsükkel lõpeb.

Nii et kui me juhime seda praegusel kujul, saame selle:

Segaduses väikesed pulgad

Praegu pole see tegelikult üldse geneetiline algoritm. Selle asemel on see pulgade komplekt, mis liigub juhuslikult valitud vektorite abil ja ekraanile tõmmatud punkt. Lisagem siis geneetiline osa.

Seega tahame, et kepp, mis teeb selle kõige kaugemale, ringile kõige lähemale, oleks kepp, mis annab oma geenid lastele edasi. Põhimõtteliselt on see kõige tugevama ellujäämine: kes elab kõige kauem, see annab edasi oma geenid.

Nii saame hakata seda rakendama, andes igale pulgale uue muutuja: sobivus.

var fitness = 0

Sobivust arvutatakse kepi hetkeasendi järgi ringi (sihtmärgi) suhtes. Saame seda rakendada funktsioonina, et arvutada iga pulga pealt Fitness.

this.calculateFitness = funktsioon () {
var distance = dist (see.pos.x, see.pos.y, target.x, target.y)
this.fitness = 1 / vahemaa
}

Nüüd on meil pulgad, millel on sobivusaste - st neil on paremad geenid, sest nad elasid kauem. Nüüd vajame viisi, kuidas saaksime reprodutseerida neid tipptasemel geenidega pulgakesi. Sisenege, bassein:

Niisiis, selle basseini kontseptsioon on suhteliselt sirge. Oleme juba eespool mõelnud, et kõige edukamad geenid on need, mis on ringile kõige lähemal. Mida lähemal kepp on, seda rohkem kordi selle genoomi basseini sisestatakse ja seda tõenäolisem on selle paljunemine. Kepil, mis tegi sellest 5% kogu teisest küljest, on 5% reprodutseerimise võimalus, samas kui kepil, mis tegi selle 70% muust, on reprodutseerimise võimalus 70%. Loodetavasti selgitasin seda piisavalt hästi. Edukam kepp = parem võimalus uue kepi osana uuesti sündida.

Eespool on kaks uut funktsiooni. Valik on, nagu nimigi viitab, vanema geenide valimine geenivaramust. Seejärel ühendatakse need geenid, moodustades rist DNA-s uue DNA, mis omakorda omistatakse uuele pulgale! See on üsna palju, kuna tahame säilitada selle suhteliselt lihtsa ja algelisena.

Päris lahedad, meie pulgad suudavad nüüd võtta eelkäijate parimad võimalused ja kasutada neid ringi leidmiseks! Kui vaatame seda nüüd tegevuses:

Ikka segane, kuid pisut nutikam tikk.

Pärast mitukümmend iteratsiooni hakkab välja nägema, nagu oleks nad kadunud, kuna ainult mõned read on nähtavad. Kuid see pole nii: mida kergem kepp, tähendab see, et mitu keppi järgivad täpselt sama rada. See on ootuspärane, kuna meil on suhteliselt vähe geene.

Väga nutikad alfakepid.

Mida kauem see töötab, seda rohkem ilmub ekraanile ainult üks kepp. See kepp tähistab optimaalset keppi! Valitud kepp. Siin nad on, meie geneetilise algoritmi kulminatsioon:

Geeniusekepp (id)!

See on geneetilise evolutsiooni algoritm, kirjutatud täielikult brauserisse! See ei ole kindlasti geneetilise evolutsiooni täiuslik näide, kuid see on hea näide sellest tööl. Meie väike tikk võib nüüd ringi saada ja see, mis järgneb, pole täna veel teema.

Nagu alguses mainitud, mõjutab seda suuresti The Coding Train. Link nende repole.

Minu täielik kood.