Найти - Пользователи
Полная версия: Генетический алгоритм
Начало » Python проекты » Генетический алгоритм
1
pasaranax
Некоторое время назад я создавал темку про алгоритмы оптимизации и свою с ними проблему. Не найдя лучшего решения, я в тот же день начал разработку собственного Генетического алгоритма.
Задача моя была - оптимизировать конфиг-файл для биржевого робота, с чем он успешнее аналогов справляется. Тем не менее я старался его сделать максимально универсальным в использовании, и надеюсь, это получилось.
По интерфейсу он похож на алгоритмы оптимизации из scipy и pybrain. Зависимостей у него нет, только matplotlib, если интересно наблюдать график эволюционного прогресса.
Надеюсь, любителям мат. моделей с красивыми названиями понравится :) Алгоритм я использую в работе, так что буду его поддерживать на гитхабе. Он местами несовершенен (например, график надо сделать в отдельном потоке), возможно содержит баги. Если такие найдете, сообщите мне.

Проект на Гитхабе



Пример использования для решения диофантова уравнения взял из статьи на хабре. На гитхабе есть версия этого текста в более красивой разметке.

Попробуем найти одно из решений диофантова уравнения (с целочисленными корнями): a + 2b + 3c + 4d = 30. Фитнес-функция example_equation получает на вход список предположительных корней уравнения и возвращает отрицательное расстояние (чем больше фитнес, тем лучше) до его равенства (30). То есть при корнях являющихся решением, фитнес-функция вернет 0, во всех других случаях отрицательное число, которое чем ближе к нулю, тем больше наши корни похожи на решение.

def example_equation(x):
    '''Equation: a + 2b + 3c + 4d = 30'''
    a, b, c, d = x
    z = a + 2*b + 3*c + 4*d
    ans = 30
    print("{:.0f} {:+.0f}*2 {:+.0f}*3 {:+.0f}*4 = {:.0f}".format(a, b, c, d, z), "- Solved!" if z == ans else "")
    return -abs(ans-z)

Параметры конструктора:

steps = 40 - дадим эволюции не более 40 поколений
stop_fitness = 0 - останавливаем эволюцию, когда функция вернула 0, значит решение найдено
bounds = (-100, 100, 1) - предположим корни лежат где-то в диапазоне (-100, 100), шаг единица, поскольку корни целочисленные. От шага зависит точность поиска решения. Иррациональные корни ГА не найдет.
num_genes = 4 - у нас 4 корня
stagnation = 3 - если эволюция войдет в застой на 3 поколения, применяем катаклизм (более сильная мутация)
mutagen = “1_step” - у каждой особи (потенциального решения) при рождении создаем мутацию - меняем один из параметров на размер шага
cata_mutagen = “full_step” - если мы вошли в стагнацию, применяем катаклизм - меняем все параметры на размер шага
population_limit = 10 - в каждом поколении будем тестировать 10 вариантов решения (особей)
survive_coef = 0.2 - из каждого поколения выбираем 20% лучших решений (то есть 2 особи из 10 смогут оставить потомков)
productivity = 4 - на каждую из двух выживших особей после скрещивания приходится 4 потомка, то есть в новом поколении будет 8 потомков, остальные 2 места в популяции займут особи сгенерированные случайным образом
plot = True - если установлен matplotlib, будем наблюдать эволюционный прогресс на графике

if __name__ == '__main__':
    ga = GA(example_equation, bounds=(-100, 100, 1), num_genes=4, steps=40, stop_fitness=0, stagnation=3, 
            population_limit=10, survive_coef=0.2, productivity=4, mutagen="1_step", cata_mutagen="full_step",
            plot=True)
    result = ga.evolve()
    print("Best solution:", result)
Большинство параметров можно оставить по умолчанию, обязательны первые три.

Результат работы:
- Step 10 / 40 results: best: -2.000, spread: 4.000, elapsed: 0m 1s, remaining: 0m 0s
-100 +68*2 -66*3 +48*4 = 30 - Solved!
-100 +67*2 -65*3 +48*4 = 31
-99 +67*2 -66*3 +47*4 = 25
-100 +67*2 -66*3 +48*4 = 28
-99 +67*2 -66*3 +48*4 = 29
-100 +67*2 -67*3 +47*4 = 21
-100 +67*2 -66*3 +46*4 = 20
-100 +68*2 -66*3 +48*4 = 30 - Solved!
-76 -30*2 +69*3 +69*4 = 347
27 -73*2 -32*3 -20*4 = -295
- Step 11 / 40 results: best: 0.000, spread: 0.000, elapsed: 0m 1s, remaining: 0m 0s
- Evolution complete: best fitness = 0.000 <= 0.000
Best solution: (, 0)
4kpt_IV
А что Вы читали по ГА, до того как это написать?
pasaranax
4kpt_IV
А что Вы читали по ГА, до того как это написать?
Немного наслушался от куратора по диплому еще в институте. А в основном статьи в интернете, на том же хабре.
4kpt_IV
Просто ГА уже шагнуло давно вперед. Есть механизмы для определения оптимальных параметров ГА, так называемый тестовый ГА, есть принцип управляемых мутаций и т.п. Вы сделали колоссальную работу, но по очень “каноничному” ГА. А вот сходимость у него низкая Можете проверить на тестовых функциях нелинейного программирования…
pasaranax
А можно примеры на которых вы проверяли? И материалы для изучения, если есть под рукой?
Мой алгоритм достаточно простой, я бы не назвал работу колоссальной. И я бы, пожалуй, вовсе не стал его разрабатывать, если бы нашел решение на питоне либо такое же простое в применении, либо с хорошей документацией.
Мне генетический алгоритм сам по себе нравится, и я готов эту реализацию развивать, если это будет интересно )
4kpt_IV
Банди. Методы оптимизации. Вводный курс. Страница 36,37. Там есть несколько тестовых функций. Для начала Вам должно хватить. Сравнивать сходимость можно с методами прямого поиска типа метода “Нелдера-Мида”.
Shaman
pasaranax
он успешнее аналогов справляется
Была ли Deap среди этих аналогов?
pasaranax
Shaman
Была ли Deap среди этих аналогов?
Вроде нет, я сравнивал только с теми, что были в pybrain и scipy
Shaman
Ясно. В таком случае альтрнативу ей искать пока не буду.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB