- PVSM.RU - https://www.pvsm.ru -
Этим летом я принял участие в Научно-образовательной школе МГУ [1], которая проводится Московским Государственным Университетом и Лабораторией Научного Творчества СУНЦ МГУ [2]. В этой статье я хотел бы рассказать вам о проекте, который я разработал во время школы на спецкурсе по программированию под руководством MAD_GooZe [3].

Для нетерпеливых [4]
Итак, у нас возникла идея сделать что-нибудь интересное, используя генетические алгоритмы. Например — попытаться генерировать красивые абстрактные изображения. К слову сказать, до начала работы над этим проектом, я был знаком с генетическими алгоритмами весьма посредственно, но пообщавшись с руководителем и почитав некоторые статьи в интернете, я ринулся в бой.
Итак, как вы, наверное, знаете, генетические алгоритмы основываются на принципах эволюции. Они позволяют решать задачи, «идеальное» решение которых не определено, или метод прямого его получения не известен. Обычно, реализации таких алгоритмов состоят из следующих этапов:
Расскажем о реализации этих шагов в нашем проекте.
Мы будем представлять картинки в цветовом пространстве RGB, в котором цвет каждого пикселя представляется с помощью 3 компонент – красной, зелёной и синей, каждая из которых принадлежит промежутку [0; 255]. Будем задавать изображение, как набор трех функций r(x, y), g(x,y), b(x,y) — по одной функции на каждую компоненту цвета. Как нарисовать картинку по этим функциям?

, и округлим.Формулы же мы будем представлять в виде деревьев. Например, так:

Так как функции мы представляем в виде деревьев, мы можем легко сгенерировать начальное поколение. Каждую функцию просто собираем из составных частей (других функций, констант и аргументов). Используются такие функции-примитивы:
| Унарные | Бинарные |
|---|---|
| |a| | a + b |
| cos(a) | a — b |
| sin(a) | a * b |
| ln(a) | a / b |
| arccos(a) | a mod b |
| arcsin(a) |
При этом, тут есть некоторые особенности:
, где n – глубина текущего узла, а N – максимальная глубина дерева, в данный узел помещается элемент без потомка (т. е. константа или координата, в отличие от функций, которые обязаны иметь потомки, так как они являются их аргументами). Данная формула была подобрана экспериментально, исходя из следующих требований:
, т. е. глубина функции не может превысить максимальную;
Пример случайно сгенерированного поколения:

Вполне ожидаемо, что практически все случайные изображения выглядят скучновато. Для исправления этого печального факта нам, собственно, и нужны генетические алгоритмы.
Кстати, отдельное изображение каждого канала тоже выглядит не интересно, но втроём они образуют красивые цветовые эффекты.

После генерации первого поколения необходимо провести оценку полученных решений. Оценивать «красивость» изображений автоматически несколько затруднительно, поэтому это задача ложится на плечи пользователя: сначала он выбирает самое понравившееся из полученных изображений (ему выставляется максимальная оценка), затем наилучшее из оставшихся и так далее.
После выставления оценки необходимо провести скрещивание особей, чтобы получить новое поколение. Для получения изображения-потомка необходимо 2 родителя. Вероятность каждой особи стать родителем прямо пропорциональна ее оценке.
Используемый здесь алгоритм скрещивания является разновидностью многоточечного скрещивания, приспособленного под данную задачу, т. е. гены потомка – набор из частей генов родителей, взятых в определённом порядке, причем:
Примеры скрещивания:


После получения потомка необходимо его мутировать, чтобы не терялось разнообразие поколений. Мутация применяется ко всем потомкам и заключается в следующем – обходятся все 3 функции изображения и в каждой из них константы/координаты с определённой вероятностью меняются на другие константы/координаты.
Пример мутации:

30% лучших изображений переносится в новое поколение из старого, чтобы случайно не потерять их гены. А остальные изображения в поколении — результат скрещивания. Это позволяет сохранить баланс между разнообразием особей и преемственностью «качественных» генов.

Реализация этого проекта написана на JavaScript. Изображения отрисовываются на canvas, их обсчет происходит в web workers, для ускорения работы.
С этим проектом я участвовал в конференции научных работ школьников Ученые Будущего [6], и занял там 4 место, что для ученика 8 класса, наверное, неплохо :).
Статья подготовлена в рамках Научно-образовательной школы МГУ [1] вместе с моим руководителем MAD_GooZe [3].
Автор: nbashaev
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/51962
Ссылки в тексте:
[1] Научно-образовательной школе МГУ: http://lanat.ru
[2] Лабораторией Научного Творчества СУНЦ МГУ: http://aesc.msu.ru
[3] MAD_GooZe: http://habrahabr.ru/users/mad_gooze/
[4] Для нетерпеливых: http://aesc.msu.ru/~gusev/abstract-images/
[5] GitHub: https://github.com/nbashaev/Abstract
[6] Ученые Будущего: http://intel.festivalnauki.ru/
[7] Создание картинок с помощью градиентов: http://habrahabr.ru/company/luxoft/blog/150966/
[8] Генератор визуальных интерфейсов: http://habrahabr.ru/post/203156/
[9] Генерация картинок, отдаленно похожих на лица людей: http://gryaznulka.livejournal.com/1698282.html
[10] Источник: http://habrahabr.ru/post/205892/
Нажмите здесь для печати.