Бърз пример за генетична еволюция в JavaScript: Нека направим бебе.

„Процесът на мутация е единственият известен източник на новите материали за генетична променливост и следователно за еволюцията.“ - Добжански, 1957г.

Алгоритмите на генетичната еволюция са наистина очарователни за мен. Способността за програмиране на виртуална ДНК е просто феноменален подвиг на компютърните науки. Способността да се напише, като код, теорията на Дарвин за еволюцията и действително да се види оцеляването на модела Fittest в действие е просто изумителна.

Никога преди не съм се докосвал до генетични алгоритми и реших, че е време да започна. И кое по-добро място за начало от действителното, старт, нали? В този урок ще създам „пръчка“ и тази пръчка иска да достигне до „кръг“. Предполагайте, че ще искате, но аз пиша уроци за семейството и това ще остане така.

Взимам невероятно тежко влияние от The Coding Train: Coding Challenge # 29 като вдъхновение за това. Линк към него тук. Той беше вдъхновен от Smart Rockets, така че докато аз не правя нещо ново или оригинално, надявам се той да послужи като пример за алгоритъм за генетична еволюция. Използвам библиотеката P5.JS, която бих обобщила като визуална библиотека на JavaScript.

Преди да мога да създам всякакъв вид генетичен алгоритъм, първо трябва да настроя действителната настройка. Първо създавам много проста HTML страница.

Имам две библиотеки за P5. Главна обработва рисунката към екрана, създаване на променливи и т.н. Стик е линията, която ще се развива, популацията е колекция от пръчки, а dna е това, което бих считал сърцевината на генетичния алгоритъм. Нека да разгледаме кода за Stick:

Така че една пръчка има някои основни характеристики. Тя трябва да може да се движи, така че да има двигател за движение (за желание на по-добър термин) в променливите на скоростта, ускорението и позицията. В момента цялото движение се контролира от тайнствената ДНК функция. Преди да стигнем до ДНК, нека разгледаме популацията:

Населението наистина не е толкова интересно. Той създава 25 пръчки, които смятам, че са достатъчни за популация и след това ги премества на екрана. Разбиване на бариери с тази функция! ДНК:

В този момент ДНК не прави нищо. Една пръчка получава една ДНК, а една ДНК има набор от 200 гена, което е дължината на живота ми за малката ми пръчка. Не се притеснявайте, повече ще бъдат добавени след време. Основният файл:

Така че Main прави доста неща тук. Първо, ние трябва да създадем ново поколение пръчки, което представлява инстанция на населението, а след това създаваме нашия кръг, към който пръчките ще се стремим по-късно надолу по линията. Тогава ние рисуваме всичко на екрана, с добавената способност да убиват и създават ново поколение, всеки път, когато техният жизнен цикъл приключи.

Така че, ако изпълним това, както е в момента, получаваме това:

Обърканите малки пръчици

В този момент това изобщо не е генетичен алгоритъм. Вместо това е набор от пръчки, движещи се на произволно избрани вектори, с точка, изчертана на екрана. Затова нека добавим генетичната част.

Така че ние искаме пръчката, която я прави най-отдалечената, най-близо до кръга, да бъде пръчката, която предава гените си на децата си. Това е основно оцеляване на най-силните: който оцелее най-дълго, той трябва да предаде гените си.

Така че можем да започнем да прилагаме това, като даваме на всяка пръчка нова променлива: фитнес.

вар фитнес = 0

Фитнесът ще се изчислява според текущото положение на пръчката, спрямо положението на кръга (целта). Можем да реализираме това като функция, за да изчислим Fitness на всяка пръчка.

this.calculateFitness = функция () {
var distance = dist (this.pos.x, this.pos.y, target.x, target.y)
this.fitness = 1 / разстояние
}

Сега имаме пръчки, които имат фитнес рейтинг - т.е. имат по-добри гени, защото оцеляват по-дълго. Така че сега се нуждаем от начин да можем да възпроизведем тези пръчки с най-високо ниво на гени. Влезте, басейнът:

Така че този пул е сравнително прав напред в концепцията. Вече разбрахме по-горе, че най-успешните гени са тези, които са най-близо до кръга. Колкото по-близо е пръчката, толкова повече пъти геномът ще бъде въведен в пула и толкова по-голяма е вероятността да се възпроизвежда. Една пръчка, която го направи 5% от пътя, ще има 5% шанс за възпроизвеждане, докато пръчката, която го направи 70% от пътя, има 70% шанс да се възпроизведе. Надявам се, че обясних това достатъчно добре. По-успешен стик = по-голям шанс да се преродиш като част от нова пръчка.

Горното е две нови функции. Изборът е, както би означавало името, избиране на родителските гени от генофонда. След това тези гени се комбинират, за да образуват нова ДНК в кросоувър, която от своя страна след това се възлага на новата пръчка! Това е почти всичко, тъй като искаме да запазим това относително просто и рудиментарно.

Доста готино, нашите пръчки вече са в състояние да вземат най-доброто от способностите на предшествениците и да ги използват, за да намерят кръга! Ако сега го разгледаме в действие:

Все още обърканите, но малко по-умни пръчки.

След няколко десетки повторения започва да изглежда, че те отмират, тъй като се виждат само няколко реда. Но това не е така: колкото по-леката е тоягата, това означава, че множество пръчки следват точно същия път. Това може да се очаква, тъй като имаме сравнително ограничен пул от гени.

Много умни, алфа пръчки.

Колкото по-дълго е оставено да работи, толкова повече ще се появява само една пръчка на екрана. Тази пръчка представлява оптималната пръчка! Избраната пръчка. Ето ги, кулминацията на нашия генетичен алгоритъм:

Гениална пръчка (и)!

Това е алгоритъм за генетична еволюция, написан изцяло в браузъра! Това не е перфектен пример за генетична еволюция, сигурно, но това е прекрасен пример за това в работата. Нашата малка пръчка може да продължи, за да получи кръга и какво следва по-нататък, не е тема за днес.

Както бе споменато в началото, това е силно повлияно от The Coding Train. Връзка към тяхното репо.

Моят пълен код.