Я создаю проект, основная цель которого - найти заданное число (если возможно, в противном случае возможно ближайшее), используя 6 заданных чисел и основные операторы (+, -, *, /). Идея состоит в том, чтобы случайным образом генерировать выражения, используя заданные числа и операторы, в обратной шлифованной (постфиксной) нотации, потому что я нашел ее проще всего генерировать и вычислять позже. Эти выражения являются Индивидуумами в Популяции моего Генетического Алгоритма. Эти выражения имеют форму ArrayList of Strings в Java, где Strings являются как операторами, так и операндами (указанными числами).
Главный вопрос здесь заключается в том, как лучше всего объединить этих людей (фактически, постфиксные выражения)? Прямо сейчас я думаю о перекрестных выражениях, составленных из всех шести заданных операндов (и 5 операторов с ними). Позже я, вероятно, также буду скрещивать выражения, которые будут состоять из меньшего количества операндов (5, 4, 3, 2 и тоже только 1), но я думаю, что я должен сначала разобраться с этим, как с самым сложным случаем (если вы думаю, было бы лучше начать по-другому, я открыт для любых предложений). Итак, дело в том, что каждое выражение составляется из всех заданных операндов, а также в дочернее выражение должны быть включены все операнды. Я понимаю, что для этого требуется своего рода упорядоченный кроссовер (часто используемый в таких задачах, как TSP), и я много читал об этом (например, здесь, где описаны несколько методов), но я не совсем понял, какой из них будет лучше в моем случае (я также знаю, что в Genetic Algorithms есть много методом проб и ошибок, но я говорю о другом).
То, что я говорю, беспокоит меня, это операторы. Если бы у меня был только список операндов, то не было бы проблемой пересечь 2 таких списка, например, взяв случайный подмассив половинных элементов из 1 родителя, и заполнить остальные оставшимися элементами из родителя 2, сохраняя порядок, например это было. Но вот если я, скажем, возьму первую половину выражения из первого родительского выражения, мне обязательно придется заполнить дочернее выражение оставшимися операндами, но что мне делать с операторами? Возьмите их из родителя 2, как и остальные операнды (но тогда мне придется остерегаться, потому что для использования оператора в постфиксном выражении мне нужно иметь как минимум еще 1 операнд, и проверка этого все время может занять много времени, или нет?), или, может быть, я мог бы сгенерировать случайные операторы для остальной части дочернего выражения (но тогда это не было бы чистым пересечением, не так ли)?
Говоря о кроссовере, есть еще и мутация, но, думаю, я это проработал. Я могу взять выражение и выполнить мутацию, при которой я просто поменяю местами 2 операнда, или взять выражение и случайным образом изменить 1 или более операторов. На этот счет у меня есть некоторые идеи, но кроссовер — это то, что меня действительно беспокоит.
Итак, это в значительной степени суммирует мою проблему. Как я уже сказал, главный вопрос заключается в том, как выполнить пересечение, но если у вас есть какие-либо другие предложения или вопросы по программе (возможно, более простое представление выражений, кроме списка строк, что может быть проще/быстрее для пересечения, может быть, что-то, что я не сделал не упоминать здесь, это не имеет значения, может быть, даже совершенно новый подход к проблеме?), я хотел бы их услышать. Я не дал здесь никакого кода, потому что не думаю, что он нужен для ответа на этот вопрос, но если вы считаете, что это поможет, я обязательно отредактирую, чтобы решить эту проблему. Еще раз, главный вопрос в том, чтобы ответить, как пересечь эту конкретную часть проблемы (ожидается идея или псевдокод, хотя сам код тоже был бы хорош :D), но если вы считаете, что мне нужно изменить что-то еще, или вы знаете какие-то другие решения всей моей проблемы, не стесняйтесь говорить.
Заранее спасибо!