Привет, хабр! Этим летом я принял участие в Научно-педагогическая школа МГУ , который проводят Московский государственный университет и Лаборатория научного творчества ЮНЦ МГУ .
В этой статье я хотел бы рассказать вам о проекте, который я разработал во время специального курса программирования в школе под руководством MAD_GooZe .
Идея проекта
И у нас возникла идея сделать что-то интересное, используя генетические алгоритмы.Например, попробуйте создать красивые абстрактные изображения.
Кстати, до начала работы над этим проектом я был весьма посредственно знаком с генетическими алгоритмами, но пообщавшись с руководителем и прочитав несколько статей в Интернете, я ринулся в бой.
Принцип действия
Итак, как вы, наверное, знаете, генетические алгоритмы основаны на принципах эволюции.Они позволяют решать задачи, для которых не определено «идеальное» решение или неизвестен метод непосредственного его получения.
Обычно реализации таких алгоритмов состоят из следующих этапов:
- Генерация случайной генерации индивидуумов решения
- Отбор самых качественных особей поколения
- Скрещивание особей для получения потомков
- Мутация потомков
- Получение нового поколения
О представлении изображений
Мы будем представлять изображения в цветовом пространстве RGB, в котором цвет каждого пикселя представлен тремя компонентами — красным, зеленым и синим, каждый из которых принадлежит интервалу [0; 255].Определим изображение как набор трёх функций r(x, y), g(x,y), b(x,y) — по одной функции для каждой цветовой составляющей.
Как нарисовать картинку на основе этих функций?
- Пройдемся по всем пикселям изображения и найдем для них значения этих функций, передав в качестве аргументов координаты пикселей по осям x и y;
- Отдельно для каждой функции нормализуем полученные значения, то есть приведем их в диапазон от 0 до 255, по формуле
, и округляем его.
Например, вот так:
Генерация случайной генерации изображений
Поскольку мы представляем функции в виде деревьев, мы можем легко сгенерировать начальное поколение.Мы просто собираем каждую функцию из ее составных частей (других функций, констант и аргументов).
Используются следующие примитивные функции:
Унарный | Двоичный |
---|---|
|а| | а+б |
потому что (а) | а - б |
грех(а) | а*б |
пер(а) | а/б |
арккос(а) | мод б |
арксисин(а) |
- Мы не можем создавать слишком сложные функции, так как это создаст проблемы с производительностью.
Поэтому вводится такой параметр, как максимальная глубина дерева функций.
Экспериментально выбранным оптимальным значением этого параметра является число 6, так как слишком глубокие (и, следовательно, сложные) функции, помимо упомянутой проблемы, создают еще и рябь при формировании изображений, что снижает их качество, а слишком простые функции генерируют примитивные изображения.
- Во-вторых, для достижения разнообразия первого поколения генерируемые функции должны отличаться друг от друга по своей структуре, т. е.
количеству и расположению вилок, а также длине ветвей.
Поэтому был придуман следующий метод генерации изображений.
С вероятностью
, где n — глубина текущего узла, а N — максимальная глубина дерева, в этот узел помещается элемент без дочернего элемента (т. е.константа или координата, в отличие от функций, которые должны иметь дочерние элементы, поскольку они являются их аргументы).
Данная формула была выбрана экспериментально исходя из следующих требований:
- Функция увеличивает свое значение по мере увеличения n;
- Когда n = N
, т.е.глубина функции не может превышать максимальную;
- Субъективный критерий: создаваемые изображения не являются ни слишком простыми, ни слишком сложными.
- Никто не мешает генерировать константные функции (которые не зависят от своих аргументов).
В этом случае значение компонента устанавливается равным 0 для всех пикселей.
Вполне ожидаемо, что почти все случайные изображения выглядят немного скучно.
Чтобы исправить этот печальный факт, нам действительно нужны генетические алгоритмы.
Кстати, отдельное изображение каждого канала тоже выглядит неинтересно, но зато они втроем образуют красивые цветовые эффекты.
Оценка изображений за поколение
После генерации первого поколения необходимо оценить полученные решения.Автоматически оценить «красоту» изображений несколько сложно, поэтому эта задача ложится на плечи пользователя: сначала он выбирает наиболее понравившееся из полученных изображений (ему присваивается максимальный рейтинг), затем лучшее из оставшихся , и так далее.
Скрещивание
После проведения оценки необходимо скрестить особей для получения нового поколения.Для получения изображения ребенка необходимы 2 родителя.
Вероятность того, что каждый человек станет родителем, прямо пропорциональна его баллу.
Используемый здесь алгоритм скрещивания представляет собой адаптированный для этой задачи тип многоточечного скрещивания, т.е.
гены потомка представляют собой набор частей генов родителей, взятых в определенном порядке, и:
- Пересечение не может привести к неправильной функции
- Изображение с более высоким баллом приносит больше пользы ребенку
Мутация
После получения потомка необходимо его мутировать, чтобы не потерялось разнообразие поколений.Мутация применяется ко всем потомкам и заключается в следующем: обходят все 3 функции изображения и в каждой из них константы/координаты меняются на другие константы/координаты с определенной вероятностью.
Пример мутации:
Формирование нового поколения
30% лучших изображений передаются в новое поколение из старых, чтобы случайно не потерять свои гены.А остальные изображения в генерации — результат скрещивания.
Это позволяет сохранять баланс между разнообразием особей и преемственностью «качественных» генов.
Техническая реализация
Реализация этого проекта написана на JavaScript. Изображения рисуются на холсте и обрабатываются веб-работниками для ускорения работы.
Результаты
С этим проектом я участвовал в конференции научных работ школьников.Ученые будущего , и занял там 4-е место, что, наверное, неплохо для 8-го класса :).
Ссылки по теме
- Создание изображений с помощью градиентов
- Генератор визуального интерфейса
- Создание изображений, отдаленно напоминающих лица людей.
Теги: #генетические алгоритмы #JavaScript #цифровое искусство #JavaScript #Алгоритмы
-
Этапы Ремонта Компьютеров И Ноутбуков
19 Dec, 24 -
Протокол Ospf В Quagga (Одна Зона)
19 Dec, 24 -
Мы Пишем Плагин Для Netbeans. Часть Вторая
19 Dec, 24 -
Конференция-Фестиваль Mobilefest 2012
19 Dec, 24 -
Чего Никто Не Говорит Новичкам
19 Dec, 24 -
Еще Несколько Идей (Интернет)
19 Dec, 24