2015-04-13 5 views
3

Я пытаюсь построить типизированное генетическое программирующее решение с DEAP.Как исправить «gp.generate попытался добавить примитив, но нет доступных»?

Я запускаю программу с фотографией черного & белого треугольника и трех вершин другого треугольника. Надежда состоит в том, что программа придумает программу, которая перемещает вершины данного треугольника ближе к той, что находится на фотографии. Я предоставляю ему случайные константы, арифметические примитивы добавляют, вычитают и т. Д., Если-then-else. и тесты для is_black и is_white при заданных координатах.

Я установил все свои примитивы, но я продолжаю сталкиваться с этой ошибкой, которая, кажется, говорит мне добавить больше примитивов, которые либо обеспечивают, либо потребляют (не уверены, какие ?!) фото.

Я нахожу ошибки трудно, потому что:

  • У меня есть примитивы, которые используют фотографию в качестве входных данных.
  • У меня нет есть примитивы, которые производят фотографию как выход.
  • Я не хочу превращать фотографию, просто уничтожаю ее.

Я думаю, что победившая программа будет длинной последовательностью команд типа «если (10,10) является черным, добавьте (3,2) в вершину 1», повторив несколько тошнотворно.

Но, возможно, есть что-то, что я неправильно понимаю о том, как работает deap. Как я могу преодолеть такие сообщения об ошибках?

File "/usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/lib/python3.4/random.py", line 255, in choice 
    raise IndexError('Cannot choose from an empty sequence') 
IndexError: The gp.generate function tried to add a primitive of type '<class 'triangles.Photo'>', but there is none available. 

Эта ошибка обычно срабатывает от gp.gengrow, когда он пытается сформировать начальную популяцию.

Что может быть или не быть связано, так это то, что у меня мало возможностей для терминалов: я не совсем понимаю, как они относятся к моей проблеме.

Я ожидаю услышать сверчки, но если кто-то действительно интересуется этим вопросом и хочет видеть код или, по крайней мере, примитивный набор, я могу его наклеить или наклеить где-нибудь. Понял, что это уже слишком часто блуждало; в то время как я сосредоточился на конкретном сообщении об ошибке, я ожидаю, что это будет моим общим (un) признанием работы GP/DEAP, которая виновата.

ответ

0

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

for i in range(0, PLANE_SIZE): 
    pset.addTerminal(i, int, name=str(i)) 

Я нашел некоторое представление о проблеме в комментариях here; измененная версия функции generate от DEAP.

Это все о количестве слоев, или глубины, дерева: genGrow просит что-то, который возвращает нужный тип плюс правой глубины.

Иногда ему нужен результат «int» в одном слое (терминале), а иногда ему нужен результат int, который потребляет два слоя (функция).

Следовательно, сообщение «NONE AVAILABLE»: у него нет доступных, которые соответствуют и тип и глубина, необходимые для подключения к дереву.

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

1

Я нашел исправление этой проблемы.

Когда мне нужна тип входа только в терминалах (как вы это делали) Я создаю функцию тождества:

pset.addPrimitive(idem, [MyClass], MyClass) 

который создает длинные ветви вложенных idems правой глубины: Меты (Меты (Меты (х))) ...

Затем я строю primitivetree, заменим все эти вложенные idems на один «x» и снова преобразует строку в primitivetree с помощью deap.gp.PrimitiveTree.from_string (string, pset).

Это не изящный, это не пифонический, но он работает для меня.