Кроссовер в генетическом алгоритме для TSP

Я пытаюсь решить Проблема с продавцом (TSP) с Генетический алгоритм

My Genome - это перестановка вершины в графе (путь для продавца).

Как выполнить операцию кроссовера над моими геномами?

Где я могу найти реализацию моей проблемы в С#?

Ответ 1

Вы должны проверить "Генетический алгоритм решения TSP, избегающего специальных кроссоверов и мутаций" Гоктурка Уколока. PDF здесь. Он дает обзор специальных операторов кроссовера для перестановок и предлагает умное представление перестановок, которое хорошо работает со стандартным кроссовером (т.е. Пересечение двух перестановок всегда создает две перестановки).

Ключевым понятием является представление перестановки в качестве ее последовательности инверсии, т.е. для каждого элемента i, хранить в a[i], сколько элементов больше, чем i слева от i в перестановке. В отличие от прямого представления, единственное ограничение на a[i] является локальным, т.е. a[i] не может быть больше, чем N - i. Это означает, что простой кроссовер двух действительных инверсионных последовательностей всегда создает две допустимые последовательности инверсии - нет необходимости в специальной обработке повторяющихся элементов.

Ответ 2

Вместо того, чтобы использовать стандартную методику пересечения GA (как обозначенную MusiGenesis), лучше использовать заказал перекресток для проблемы с Traveling Salesman.

Обычный подход не работает так хорошо для TSP, потому что функция фитнеса очень чувствительна к относительным позициям разных городов на развитом маршруте, а не к их абсолютным позициям. Например, если вы посещали все европейские столицы, самый короткий маршрут не зависит от того, посещаете ли вы Братиславу 1, 2 или 9 место. Еще важнее то, что вы посещаете его сразу или сразу после посещения Вены, а не посещать Хельсинки, Афины и еще 6 других столиц между ними.

Конечно, поскольку mjv также указывает, традиционный перекресток будет также вводить дубликаты в вашем маршруте. Если один из родителей имеет Париж в позиции 2, а другой - Париж в позиции 14, перекресток может привести к одному развитому маршруту, который дважды посещает Париж (и пропускает другой город), а другой развитый маршрут, который его вообще не посещает. Упомянутый перекрестный генетический оператор не страдает от этой проблемы. Он сохраняет элементы и изменяет порядок.

Ответ 3

Вот подход С# для того, что вы ищете.

Что касается интереса (или отсутствия) реализации перекрестного перехода, все это зависит от конкретной логики выбора, которую будет использовать реализация (и/или самой функции оценки, если, например, он включает в себя оценку скорости улучшения). Во многих случаях перекрестные операции будут "спасать из блока измельчения" некоторые решения, которые эффективны/оптимальны в области графика, но как-то "застревают" в других. Это не означает, что если общий алгоритм будет достаточно медленным и покрывает хороший процент пространства решений, то одни и те же решения могут быть не обнаружены заново, но перекрестное может также увеличить эти открытия (и/или позволить вам застрять в другие локальные минимумы;-))

Не связанный напрямую, но интересный интерес для любого, кто смотрит в GA, является оригинальным "конечным" экспериментом в GA оригинальный "конечный" эксперимент в GA профессором Олдерманом (известность RSA), который использовал фактические молекулы ДНК [в программу C - просто шутки] для решения связанной задачи графа - гамильтоновых графов.

Изменить. При повторном чтении вопроса я понимаю, почему вы спросили его или, точнее, , почему вам нужен ответ "Нет, вы не хотите перекрещивать" strong > ;-)
Ваш genonme напрямую привязан к самому графику (это не так неправильно, априори), но это создает препятствие, которое большинство перекрестных отключений не будет жизнеспособным, поскольку они могут иметь дублирующие узлы ( посещать один и тот же город дважды и более) и упускать узлы (не посетить некоторые города)... Кроме того, жизнеспособные кросс-кавы будут влиять на похожие графики и, следовательно, могут просто увеличивать затраты на поиск по сравнению с тем, что обнаружат мутации..
Hum... Тогда, может быть, перекрестный, в этой конкретной реализации не будет очень сильно помогать алгоритму (и, действительно, взять большую часть своего процессора для создания, тестирования и часто отбрасывать перекрестные потомки, CPU который лучше использовать, обеспечивая больше итераций и более медленную скорость охлаждения...). Если не! Вы найдете умный способ выполнения перекрестных операций; -)

Ответ 4

Цель кроссовера - расширить эволюционное пространство поиска, объединив новые геномные комбинации.

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

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

Ответ 5

Вот моя точная реализация так называемого метода "частично сопоставленного кроссовера" в GA для TSP.

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

//construct a new individual with the genes of the parents
//method used is cross over mapping
//note that Individual datastrucuture contains an integer array called Genes which            //contains the route.
//
public Individual Breed(Individual father, Individual mother)
{
    int[] genes = new int[father.Genes.Length];
    int[] map = new int[father.Genes.Length + 1]; //create a map to map the indices
    int crossoverPoint1 = rand.Next(1, father.Genes.Length - 2); //select 2 crossoverpoints, without the first and last nodes, cuz they are always thje same
    int crossoverPoint2 = rand.Next(1, father.Genes.Length - 2);
    father.Genes.CopyTo(genes, 0); //give child all genes from the father
    for (int i = 0; i < genes.Length; i++) //create the map
    {
        map[genes[i]] = i;
    }
    //int[] genesToCopy = new int[Math.Abs(crossoverPoint1 - crossoverPoint2)]; //allocate space for the mother genes to copy
    if (crossoverPoint1 > crossoverPoint2) //if point 1 is bigger than point 2 swap them
    {
        int temp = crossoverPoint1;
        crossoverPoint1 = crossoverPoint2;
        crossoverPoint2 = temp;
    }
    //Console.WriteLine("copy mother genes into father genes from {0} to {1}", crossoverPoint1, crossoverPoint2);
    for (int i = crossoverPoint1; i <= crossoverPoint2; i++) //from index one to the 2nd
    {
        int value = mother.Genes[i];
        int t = genes[map[value]]; //swap the genes in the child
        genes[map[value]] = genes[i];
        genes[i] = t;
        t = map[genes[map[value]]]; //swap the indices in the map
        map[genes[map[value]]] = map[genes[i]];
        map[genes[i]] = t;
    }
    Individual child = new Individual(genes);
    return child;
}

Ответ 6

Когда я был на первом курсе в своем университете, я делал некоторые вычисления (которые занимали около 30 страниц) о влиянии различных операторов GA на конвергенцию решения. Насколько я помню, кроссовер - не лучшее решение для TSP, более подходящим решением является мутация, которая является инвертированием подпоследовательности вершин.

Пример:

до: A BCDEF GH

после: A FEDCB GH

Ответ 7

"Кроссовер" в генетических алгоритмах относится только к произвольному способу смешивания двух "генетических последовательностей", каждый из которых представляет собой конкретное решение проблемы (как последовательность соответствует решению зависит от вас). Так, например, скажем, у вас есть популяция, которая состоит из следующих двух последовательностей:

AAAAAAAAAA
BBBBBBBBBB

Один из способов рекомбинации этих двух "родительских" последовательностей состоит в случайном выборе точки пересечения (скажем, в позиции 3), приводящей к этим двум "дочерним" последовательностям:

AAABBBBBBB
BBBAAAAAAA

Или вы можете случайно выбрать две точки кроссовера (скажем, 3 и 8), что приведет к следующим двум последовательностям:

AAABBBBBAA
BBBAAAAABB

Для удовольствия и дополнительной изменчивости вы также можете ввести возможность случайных точечных мутаций:

AAABBBABAA
BBBAAAAABB

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