Метаэвристический тасование

0

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

Во всяком случае, теперь я ищу метаэвристический (GA, имитированный отжиг...), способный производить оптимальный перетасовки.

Перемешиваясь, я имею в виду, в этом контексте, непредвзятую (à la Fisher-Yates) случайную перестановку конечного множества. Как колода карт. Огромная (~ 500! Перестановки).

Значения этого набора все разные. Никаких столкновений не ожидается.

Из-за этого противоречия у меня есть некоторые трудности для реализации решения GA. Действительно, перетасованные значения не могут использоваться в качестве генов. Легко понять, почему:

#include <iostream>
#include <vector>
#define SPLICING 50 // 50|50 one-point crossover
int crossover(int gene, int DNA_length, int A, int B)
{if (gene < (SPLICING*DNA_length)/100) return A; else return B;}

int main() {
    std::vector<int> A, B, C;
    A = { 3, 4, 8, 12, 2, 0, 9, 7, 10, 20 };
    B = { 8, 10, 3, 4, 20, 0, 7, 9, 2, 12 };
    int DNA_length = int(A.size());
    for (int i=0; i<DNA_length; i++) {
        C.push_back(crossover(i, DNA_length, A[i], B[i]));
                    if (i == DNA_length/2) std::cout << "| ";
                    std::cout << C[i] << " ";}
            }

Выход: 3 4 8 12 2 | 0 7 9 2 12

Имеются два столкновения (2, 12).

Мой ожидаемый результат выглядит примерно так: 3 4 8 12 2 | 0 7 9 10 20 (без столкновения, идеальная перетасовка исходного набора).

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

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

Похоже, что функция кроссовера имеет дело с обыденностью ДНК родителей. Но я не могу окунуться в вопрос о смешивании двух нелинейно упорядоченных порядковых подмножеств (фрагментов ДНК родителей) ординального набора (целая ДНК) без столкновения!

Возможно, я могу полагаться только на мутацию для конвергенции. Нет выбора, нет родителей/детей и только функция подкачки в одном наборе (отдельная ДНК). Короче: не очень убедительно.

На самом деле легко переставить порядковые числа в единственном конечном множестве (например, тривиально: первое становится седьмым, второе, десятое и т.д.). Но я не уверен, имеет ли смысл говорить, что первая из множества А становится седьмой, когда вторая из множества В становится десятой части нового набора.

Тогда, мой вопрос:

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

Спасибо.

  • 0
    Спаривание хромосом, как правило, приведет к столкновениям в будущих поколениях, что приведет к множеству непригодных решений. Рассматривали ли вы манипулирование потомками (возможно, до или после мутации), чтобы убедиться, что в решении нет коллизий? Возможно, гены столкновения могли бы быть назначены случайным образом или назначены последовательно на основе родителей с первоначальным размещением. Это не идеал для ГА, но он может помочь в удалении всех непригодных решений. Кроме того, разве нельзя использовать мутацию, как сказать, что некоторые карты в колоде могут быть заменены другими при перетасовке?
  • 0
    Это действительно возможно, но я боюсь, что это резко увеличит коэффициент случайности. Представьте, что вы сохраняете нетронутой часть ДНК от родителя 1 [1, 4, 3, 2 |. Затем вы должны изменить часть ДНК от родительского 2 | 2, 7, 5, 0], чтобы сделать все значения уникальными в ДНК ребенка [1, 4, 3, 2 | 6 *, 7, 5, 0]. Таким образом, вторая часть этой ДНК на самом деле не отражает качества ДНК родительского 2. И если мы рассматриваем это как мутацию, эта мутация слишком важна, вероятно,> 5% всей ДНК в моем случае. Так что больше случайности, чем генетического отбора. В любом случае, спасибо за ваш ответ!
Теги:
shuffle
genetic-algorithm
heuristics

1 ответ

2
Лучший ответ

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

  1. Выбрать точки пересечения
  2. Скопируйте часть из родителя1 в пределах кроссоверных точек первому сыну.
  3. Составьте список элементов parent1, которые находятся за пределами точек пересечения
  4. Поместите элементы неиспользуемого списка в том же порядке, который используется в parent2
  5. Скопируйте эти элементы первому сыну в порядке, установленном на шаге 4.

Вы можете увидеть пример из моей книги на рисунке ниже (извините, но описания на португальском языке - пожалуйста, сравните с приведенным выше списком):

Изображение 174551

Вы можете выполнять поиск в Интернете для операторов, основанных на заказе, или, если хотите, просмотрите цифры из моей книги в книге " My Geneetic Algorithm". Цифры, которые вас интересуют, относятся к главе 10 (вы можете использовать переводчик Google для понимания легенд).

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

Я надеюсь, что это помогает.

  • 0
    Большое спасибо. Я только что реализовал это решение (одноточечный кроссовер), и оно дает многообещающие результаты! Я надеюсь, что это будет полезно для людей в такой же ситуации.
  • 0
    Стоит отметить одну вещь: существуют разные операторы кроссовера, основанные на перестановке / порядке, и они стремятся наследовать различную информацию. Предположим, у вас есть такой человек, как 1 4 5 0 2 3 6 7 , это довольно хорошо. Что хорошего в этом? Например, это 1 рядом с 4, где бы они ни встречались в строке, или это 4 находится точно во второй позиции? Вы можете посмотреть на разные операторы, которые сохраняют разные свойства хороших родителей, и это может сильно повлиять на производительность.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню