Генерация кода генетическими алгоритмами

Эволюционное программирование кажется отличным способом решения многих проблем оптимизации. Идея очень проста и с реализацией проблем не возникает.

Мне было интересно, есть ли способ эволюционно создать программу на языке ruby/python (или на любом другом языке)?

Идея проста:

  1. Создайте популяцию программ
  2. Выполнять генетические операции (селекция рулеткой или любая другая селекция), создавать новые программы с наследованием от лучших программ и т.д.
  3. Циклическая точка 2, пока не будет найдена программа, удовлетворяющая нашему условию.

Но есть еще несколько проблем:

  1. Как будут представлены хромосомы? Например, должна ли одна клетка хромосомы быть одной строкой кода?
  2. Как будут образовываться хромосомы? Если это будут строки кода, как их сгенерировать, чтобы убедиться, что они синтаксически правильны и т. д.?

Пример программы, которая может быть сгенерирована:

Создайте скрипт, который принимает N чисел в качестве входных данных и возвращает их среднее значение в качестве выходных данных.

Если были попытки создания таких алгоритмов, буду рад ссылкам/источникам.


comment
Было бы забавно, если бы одна из сгенерированных программ стерла диск. Конечно, вам понадобится какой-то способ песочницы, а затем будьте осторожны, когда открываете ящик Пандоры. Я полагаю, что была книга (хотя не могу вспомнить название), где такая программа в конечном итоге развивалась таким образом, что она взяла под контроль все машины мира и начала убивать людей;)   -  person Sébastien Nussbaumer    schedule 20.04.2011
comment
А книга? Эта идея была забита до смерти в дешевой научно-фантастической литературе.   -  person Ira Baxter    schedule 20.04.2011
comment
Я пробовал это однажды. После того, как программа обрела самосознание, она захватила принтер и использовала лазер, чтобы расстрелять всех в здании.   -  person Jay    schedule 20.04.2011
comment
Что такое фитнес-функция? Этим эволюционным методам нужен способ подсчитать, насколько хорошо они соответствуют некоторым критериям.   -  person Paddy3118    schedule 20.04.2011
comment
Ответ Дживайна — тот, который вы хотите пометить как ответ   -  person JohnIdol    schedule 25.04.2011


Ответы (8)


Если вы уверены, что хотите это сделать, вам нужно генетическое программирование, а не генетический алгоритм. GP позволяет вам развивать программы с древовидной структурой. Что бы вы сделали, так это дали бы ему набор примитивных операций (в то время как($register), чтение($register), увеличение($register), уменьшение($register), деление($result $numerator $denominator), print , progn2 (это GP означает «выполнить две команды последовательно»)).

Вы можете создать что-то вроде этого:

progn2(
  progn2(
    read($1)
    while($1
      progn2(
        while($1
          progn2( #add the input to the total
            increment($2)
            decrement($1)
          )
        )
        progn2( #increment number of values entered, read again
          increment($3)
          read($1)
        )
      )
    )
  )
  progn2( #calculate result
    divide($1 $2 $3)
    print($1)
  )
)  

Вы бы использовали в качестве своей фитнес-функции, насколько она близка к реальному решению. И в этом заключается загвоздка, что вы все равно должны рассчитывать это традиционно*. А затем иметь что-то, что переводит это в код (выбранный вами язык). Обратите внимание, что, поскольку у вас есть потенциальный бесконечный цикл, вам придется через некоторое время прервать выполнение (проблему остановки невозможно обойти), и это, вероятно, не сработает. Дерьмо. Также обратите внимание, что мой предоставленный код попытается разделить на ноль.

* Есть способы обойти это, но, как правило, не очень далеко от этого.

person Jivlain    schedule 20.04.2011
comment
Обратите внимание, что вы можете рассчитывать на то, что любые решения, фактически созданные GP, будут гораздо более запутанными, чем это :) - person Jivlain; 21.04.2011
comment
GP разрабатывает компьютерные программы. Они традиционно представлены в памяти в виде древовидных структур, но также обычно в виде линейной структуры (последовательности команд) или графов. Какое бы представление ни работало для вас — ничто не ограничивает ГП древовидными структурами. - person Jay; 17.12.2011
comment
you have to calculate that traditionally anyway Не обязательно, особенно когда вы пытаетесь найти обратную функцию (которую часто сложнее вычислить, чем исходную функцию). Например, если вы разрабатываете функцию извлечения квадратного корня f(x), вы можете измерить пригодность по тому, насколько близко f(x*x) к x. - person Peter Olson; 15.01.2016

Это можно сделать, но для большинства приложений это работает очень плохо.

Генетические алгоритмы работают только тогда, когда функция приспособленности непрерывна, то есть вы можете определить, какие кандидаты в вашей текущей популяции ближе к решению, чем другие, потому что только тогда вы будете получать улучшения от одного поколения к другому. Я усвоил это на собственном горьком опыте, когда у меня был генетический алгоритм с одним сильно взвешенным непрерывным компонентом в моей фитнес-функции. Он доминировал над всеми остальными, и, поскольку он был непостоянным, не было постепенного продвижения к большей пригодности, потому что кандидаты, которые были почти правильными в этом аспекте, не считались более подходящими, чем те, которые были полностью неправильными.

К сожалению, корректность программы совершенно непостоянна. Является ли программа, которая останавливается с ошибкой X в строке A, лучше, чем программа, которая останавливается с ошибкой Y в строке B? Ваша программа может быть в одном символе от правильной и все равно прерываться с ошибкой, в то время как программа, возвращающая постоянный жестко закодированный результат, может пройти как минимум один тест.

И это даже не касается того, что сам код не является непрерывным при модификациях...

person Michael Borgwardt    schedule 20.04.2011
comment
Вы хотите сказать, что генетического программирования не существует? en.wikipedia.org/wiki/Genetic_programming — этот подход в настоящее время достаточно успешно используется в огромном количество проблем с поиском - person JohnIdol; 25.04.2011
comment
@JohnIdol: У меня сложилось впечатление, что это то, что заставляет ученых расплакаться от радости из-за возможности написания интересных статей об этом, но дало очень мало практических результатов, которые не были бы тривиальными или ограниченными конкретными классами задач, которые поддаются надлежащим фитнес-функциям. - person Michael Borgwardt; 25.04.2011
comment
Поскольку я не академик, я могу понять, что это могло быть вашим впечатлением (поскольку у меня были те же мысли, прежде чем я изучил этот материал), но есть ряд случаев, когда генетическое программирование решало проблемы гораздо эффективнее и с лучшими результатами, чем стандартное генетические алгоритмы могут. Например, это первый известный пример применения такого подхода к клеточным автоматам [ citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.55.7754 ] и датировано 1996 годом. С тех пор мы прошли долгий путь. - person JohnIdol; 25.04.2011
comment
@JohnIdol: это то, что говорится в статье в Википедии, но я заметил, что многие проекты, на которые есть ссылки, кажутся застойными. Что касается статьи, на которую вы ссылаетесь, я бы сказал, что она подтверждает мою точку зрения: фитнес-функция удобно непрерывна, разрабатываемая программа чрезвычайно проста (будут ли логические функции даже полны по Тьюрингу?), и проблема, которую она решает, имеет чисто академическое значение. . - person Michael Borgwardt; 26.04.2011
comment
Проблема не имеет чисто академического значения, поскольку CA-синхронизация имеет прямое применение в устойчивости к помехам при цифровой передаче, криптографии и т. д. я>программы). Я не буду больше настаивать на этом, так как я не нахожусь в крусейде или что-то в этом роде, но материал доступен там, если вы хотите узнать больше, прежде чем продолжать проповедовать. - person JohnIdol; 26.04.2011

Что ж, это очень возможно, и @Jivlain правильно указывает в своем (хорошем) ответе, что генетическое программирование - это то, что вы ищете (а не простые генетические алгоритмы).

Генетическое программирование - это область, которая еще не достигла широкой аудитории, отчасти из-за некоторых сложностей, которые @MichaelBorgwardt указывает в своем ответе. Но это всего лишь усложнения, далеко не так, что это невозможно сделать. Исследования по этой теме ведутся уже более 20 лет.

Андре Коза является одним из ведущих исследователей в этой области (посмотрите его работа 1992 года) и продемонстрировал еще в 1996 году как генетическое программирование может в некоторых случаях превзойти наивные ГА в некоторых классических вычислительных задачах (таких как развивающиеся программы для синхронизации клеточных автоматов).

Вот хороший учебник по генетическому программированию от Козы и Поли, датированный 2003 годом.

Для недавней справки вы можете взглянуть на полевое руководство к генетическому программированию (2008).

person JohnIdol    schedule 25.04.2011
comment
ссылка Учебник по генетическому программированию не работает. Вы знаете, куда она переехала с тех пор? - person Wolf; 03.04.2018
comment
@Волк, я исправил ссылку. Вероятно, он сломался, когда пару лет назад сайт Geneticprogramming.com был переработан. Говоря об этом, сайт Geneticprogramming.com сам по себе является еще одним отличным ресурсом для этого материала — на нем есть много доступных высокоуровневых обзоров различных методов общей практики. - person seaotternerd; 04.04.2018

С тех пор, как был задан этот вопрос, область генетического программирования немного продвинулась вперед, и были предприняты некоторые дополнительные попытки развить код в конфигурациях, отличных от древовидных структур традиционного генетического программирования. Вот лишь некоторые из них:

  • PushGP — разработан с целью развития модульных функций, таких как программы, используемые программистами в этой системе. хранить все переменные и код в разных стеках (по одному для каждого типа переменных). Программы пишутся путем выталкивания и извлечения команд и данных из стеков.
  • FINCH — система, которая развивает байт-код Java. Это было использовано с большим успехом для развития игровых агентов.
  • Различные алгоритмы начали развивать код C++, часто с исправлением ошибок компилятора. Это имело смешанные, но не совсем бесперспективные результаты. Вот пример.
  • Avida — система, в которой агенты развивают программы (в основном задачи логической логики) с помощью очень простого ассемблерного кода. . На основе более старой (и менее универсальной) Tierra.
person seaotternerd    schedule 01.03.2015

Язык не проблема. Независимо от языка, вы должны определить какой-то более высокий уровень мутации, иначе на его изучение уйдет вечность.

Например, поскольку любой язык Ruby может быть определен в терминах текстовой строки, вы можете просто случайным образом генерировать текстовые строки и оптимизировать их. Лучше было бы генерировать только легальные программы Ruby. Однако это также займет вечность.

Если бы вы пытались создать программу сортировки и у вас были бы операции высокого уровня, такие как «обмен», «перемещение» и т. д., тогда у вас было бы гораздо больше шансов на успех.

Теоретически кучка обезьян, стучащих на пишущей машинке бесконечное количество времени, напечатает все произведения Шекспира. На практике это непрактичный способ писать литературу. Тот факт, что генетические алгоритмы могут решать задачи оптимизации, не означает, что это легко или даже обязательно хороший способ сделать это.

person Larry Watanabe    schedule 20.04.2011
comment
Теоретически кучка обезьян, стучащих на пишущей машинке бесконечное количество времени, напечатает все произведения Шекспира. Ключевые слова в теории и бесконечное количество времени. Вероятность того, что обезьяна получит только одну строку, скажем, Быть или не быть, вот в чем вопрос, случайно нажимая клавиши, даже если мы игнорируем пробелы, знаки препинания и заглавные буквы, составляет примерно 1 из 26^30 = 1 из 2.8Е42. Если у вас есть 10 миллиардов обезьян, печатающих строку каждую секунду, шанс, что вы наберете хотя бы одну строку за 10 миллиардов лет, по-прежнему составляет всего 1 к 9:14. - person Jay; 20.04.2011
comment
@ Джей и Ларри, вот почему генетические алгоритмы работают только с непрерывной фитнес-функцией. Если ваш единственный тест на соответствие состоит в том, равна ли строка x строке y, то генетический алгоритм/программа не может определить, ближе ли строка x к строке y. Вот на что указывал Майкл: вы можете развивать одну программу так, чтобы она была точно такой же, как другая (буква за буквой), но вы не можете развивать ее функция за функцией, потому что нет постепенного состояния... программа либо работает, либо нет. 't (например, выдает исключение). - person Kiril; 21.04.2011
comment
Если вы знаете, каково желаемое конечное состояние, и вы сравниваете каждую новую итерацию с желаемым конечным состоянием каким-то инкрементным способом, то, конечно же, в конце концов вы его достигнете. Но для этого необходимо знать желаемое конечное состояние и уметь определять, находится ли что-то ближе или дальше. Если вы можете это сделать, почему бы просто не написать код для желаемого конечного состояния? Мне нужно будет прочитать некоторые из упомянутых статей, может быть, здесь есть что-то, что я упустил, но я просто этого не вижу. - person Jay; 26.04.2011

Самое большое преимущество генетических алгоритмов, как вы говорите, то, что они чертовски просты. У них не лучшая производительность или математическая подготовка, но даже если вы понятия не имеете, как решить свою проблему, пока вы можете определить ее как задачу оптимизации, вы сможете ее решить. в ГА.

Программы на самом деле не подходят для ГА именно потому, что код не является хорошим хромосомным материалом. Я видел кого-то, кто сделал что-то подобное с (более простым) машинным кодом вместо Python (хотя это было скорее моделирование экосистемы, чем GA как таковое), и вам может повезти больше, если вы кодифицируете свои программы, используя автоматы / LISP или что-то вроде тот.


С другой стороны, учитывая, насколько заманчивы GA и как практически каждый, кто смотрит на них, задает один и тот же вопрос, я почти уверен, что уже есть люди, которые где-то пробовали это - я просто понятия не имею, удалось ли кому-то из них.

person hugomg    schedule 20.04.2011
comment
...тысячам людей удалось написать ГА, которые успешно развили компьютерные программы (= генетическое программирование, ГП), которые могут конкурировать или превосходить решения, написанные людьми :-) - person Jay; 17.12.2011
comment
Да, и кстати: просто весело наблюдать, как значимое поведение возникает из первобытного пула совершенно случайных «программ» ;-) - person Jay; 17.12.2011
comment
Просто немного пунктуальности. Генетические алгоритмы имеют математическую основу (и даже не такую ​​простую): они максимизируют функцию пригодности, а с помощью кроссовера и мутации избегают локальных оптимумов. - person Fil; 10.06.2014

Удачи с этим.

Конечно, вы можете написать программу «мутации», которая читает программу и случайным образом добавляет, удаляет или изменяет некоторое количество символов. Затем вы можете скомпилировать результат и посмотреть, лучше ли результат, чем исходная программа. (Однако мы определяем и измеряем «лучше».) Конечно, в 99,9% случаев результатом будут ошибки компиляции: синтаксические ошибки, неопределенные переменные и т. д. И, конечно же, большая часть остального будет совершенно неправильной.

Попробуйте решить очень простую задачу. Скажем, начнем с программы, которая считывает два числа, складывает их и выводит сумму. Предположим, что целью является программа, которая считывает три числа и вычисляет сумму. Насколько длинной и сложной будет такая программа, конечно же, зависит от языка. Допустим, у нас есть язык очень высокого уровня, который позволяет нам читать или записывать числа всего одной строкой кода. Тогда стартовая программа состоит всего из 4 строк:

read x
read y
total=x+y
write total

Простейшей программой для достижения желаемой цели будет что-то вроде

read x
read y
read z
total=x+y+z
write total

Таким образом, путем случайной мутации мы должны добавить «read z» и «+z», всего 9 символов, включая пробел и новую строку. Давайте упростим нашу программу мутации и скажем, что она всегда вставляет ровно 9 случайных символов, что они гарантированно находятся в нужных местах, и что она выбирает из набора символов всего 26 букв плюс 10 цифр плюс 14 специальных символов = 50 символов. Каковы шансы, что он выберет правильные 9 символов? 1 из 50^9 = 1 из 2,0e15. (Хорошо, программа будет работать, если вместо «прочитать z» и «+z» она вставит «прочитать w» и «+w», но тогда я упрощаю задачу, предполагая, что она волшебным образом вставляет точно нужное количество символов. и всегда вставляет их в нужные места.Так что я думаю, что эта оценка все еще щедра.)

1 из 2.0e15 — довольно маленькая вероятность. Даже если программа запускается тысячу раз в секунду, и вы можете быстро протестировать вывод, вероятность по-прежнему составляет всего 1 из 2,0e12 в секунду, или 1 из 5,4e8 в час, 1 из 2,3e7 в день. Держите его в рабочем состоянии в течение года, и шансы на успех по-прежнему составляют всего 1 к 62 000.

Даже умеренно компетентный программист должен быть в состоянии сделать такое изменение за какие-то десять минут?

Обратите внимание, что изменения должны поступать как минимум в «пакетах», которые являются правильными. То есть, если мутация генерирует «reax z», это всего один символ от «read z», но это все равно приведет к ошибкам компиляции, и поэтому произойдет сбой.

Точно так же добавление «прочитать z», но изменение расчета на «total=x+y+w» не сработает. В зависимости от языка вы либо получите ошибки для неопределенной переменной, либо в лучшем случае она будет иметь какое-то значение по умолчанию, например ноль, и даст неправильные результаты.

Вы могли бы, я полагаю, теоретизировать поэтапные решения. Возможно, одна мутация добавляет новый оператор чтения, а затем будущая мутация обновляет вычисление. Но без расчета дополнительное чтение ничего не стоит. Как будет оцениваться программа, чтобы определить, является ли дополнительное чтение «шагом в правильном направлении»? Я вижу единственный способ сделать это — заставить разумное существо читать код после каждой мутации и смотреть, продвигается ли изменение к желаемой цели. И если у вас есть умный дизайнер, который может это сделать, это должно означать, что он знает, какова желаемая цель и как ее достичь. В этот момент было бы гораздо эффективнее просто внести желаемое изменение, а не ждать, пока оно произойдет случайно.

И это чрезвычайно тривиальная программа на очень простом языке. Большинство программ состоят из сотен или тысяч строк, и все они должны работать вместе. Вероятность того, что любой случайный процесс напишет работающую программу, астрономична.

Могут быть способы сделать что-то похожее на это в каком-то очень специализированном приложении, где вы на самом деле не делаете случайные мутации, а скорее вносите инкрементные изменения в параметры решения. Например, у нас есть формула с некоторыми константами, значения которых нам неизвестны. Мы знаем, каковы правильные результаты для некоторого небольшого набора входных данных. Итак, мы вносим случайные изменения в константы, и если результат ближе к правильному ответу, меняем оттуда, если нет, возвращаемся к предыдущему значению. Но даже при этом я думаю, что внесение случайных изменений редко бывает продуктивным. Вероятно, было бы полезнее попробовать изменить константы в соответствии со строгой формулой, например, начать с изменения на 1000, затем на 100, затем на 10 и т. д.

person Jay    schedule 20.04.2011
comment
@Jay, вы можете развить программу для компиляции, имея строгие правила мутации, соответствующие компилятору, это не обязательно сложная часть ... сложная часть - это разработка программы, которая РАБОТАЕТ (т.е. не падает при запуске или выполняет что-то полезный). В противном случае вы сделали хороший анализ. - person Kiril; 21.04.2011
comment
Я немного подумал об этом, но мой пост был слишком длинным. Вы могли бы заставить мутации генерировать токены, а не отдельные буквы, то есть полные ключевые слова, имена функций, имена переменных и т. д. Но все равно было бы трудно получить что-то похожее на случайный процесс, который по-прежнему гарантировал бы синтаксическую правильность. Например, вы можете заставить его генерировать только полные ключевые слова, такие как if и else, а не ib и els. Но даже такое простое правило, как убедиться, что все ELSE соединены с IF, потребует анализа структуры программы, что уведет нас далеко от случайных мутаций. - person Jay; 21.04.2011
comment
@Jay, правила действительно легко соблюдать. Каждый узел в дереве имеет заданное количество дочерних элементов, например, IFGT (если-больше-чем) имеет четыре дочерних элемента: IFGT(A,B,CaseA,CaseB). Дочерними функциями могут быть другие функции, такие как ADD(A,B), SWAP(A,B) или MULT(A,B)... так что теперь вы можете составить программу: IFGT(1,2,MULT(5) ,6),ADD(8,2)) где 1, 2, 5, 6 и 8 — конечные узлы. Теперь вы можете легко изменить эту программу, но все становится немного сложнее, если вы добавите нечисловые узлы, такие как SUBSTR(S1,S2). Так что сделать программу, которая компилируется, не сложно... - person Kiril; 21.04.2011
comment
Но теперь вы явно переходите от случайных мутаций к искусственному интеллекту, а это совсем другой вопрос. Когда вы начинаете говорить, что собираетесь построить карту более высокого уровня программы, определить, какие типы узлов допустимы в любой заданной точке на карте, управлять взаимосвязями между результатами операций в этих узлах и т. д., это больше не писать программу через случайные мутации и фильтр, это встраивает в мутатор много интеллекта. - person Jay; 21.04.2011
comment
@Jay Это не более высокий уровень программы, чем компилятор. Отличным примером является ДНК: A соединяется только с T, а C соединяется только с G, то есть каждый узел ДНК может соединяться только с определенным набором узлов, то же самое с узлом в GP. Это может вам помочь: технически вы можете выразить любую компьютерную программу с помощью минимального набора инструкций процессора: ADD, OR, XOR. Вы можете в значительной степени гарантировать, что любая комбинация из них всегда будет компилироваться, но даже если она скомпилируется, вы не сможете измерить, ближе ли она, скажем, к открытию файла или нет (т. е. файл не может быть открыт на 50% или на 75%). % открыть). - person Kiril; 21.04.2011
comment
@Джей, в общем... посмотри ответ Дживлейна, он попадает прямо в точку. - person Kiril; 21.04.2011
comment
@Link Хорошо, вы можете обойти компилятор и написать машинный код напрямую. Если ваш компьютер реализует каждую возможную комбинацию битов как исполняемый код операции, тогда он будет работать. Тогда ваш мутатор может случайным образом изменять или вставлять биты в программу. Но тогда у вас еще меньше шансов случайно получить программу, которая делает что-то полезное. Нет даже структуры более высокого уровня языка компилятора, чтобы навязать некоторую рациональность. Существует большая разница между запуском программы и ее выводом. - person Jay; 26.04.2011
comment
..и почему вы выбрали это глупое представление? Ввод текста — это программирование для людей. Существуют гораздо более эффективные «методы кодирования» для машин, просто посмотрите на GP с линейными, древовидными или графическими геномами (и это лишь некоторые из них). -другой Джей - person Jay; 17.12.2011
comment
другой @Jay: Конечно, это то, что я сказал в предыдущем посте: у вас может быть набор правил, чтобы ограничить изменения чем-то действительным. Я не сомневаюсь, что вы могли бы построить систему, в которой каждая мутация компилируется. Достаточно ограничений, возможно, может гарантировать, что он не рухнет. Но чем больше ограничений вы добавляете, тем меньше это случайная мутация и тем больше это искусственный интеллект. И вам еще предстоит выяснить, как решить, что программа приближается к правильному решению без интеллектуального анализа. - person Jay; 27.12.2011

Я хочу просто дать вам предложение. Я не знаю, насколько вы успешны, но, возможно, вы могли бы попытаться развить ядерную войну бот с генетическим программированием. Ваша фитнес-функция проста: просто позвольте ботам соревноваться в игре. Вы можете начать с хорошо известных ботов и, возможно, нескольких случайных, а затем подождать и посмотреть, что произойдет.

person Rafael Almeida    schedule 21.04.2011