Я пытаюсь решить Проблема с продавцом (TSP) с Генетический алгоритм
My Genome - это перестановка вершины в графе (путь для продавца).
Как выполнить операцию кроссовера над моими геномами?
Где я могу найти реализацию моей проблемы в С#?
Я пытаюсь решить Проблема с продавцом (TSP) с Генетический алгоритм
My Genome - это перестановка вершины в графе (путь для продавца).
Как выполнить операцию кроссовера над моими геномами?
Где я могу найти реализацию моей проблемы в С#?
Вы должны проверить "Генетический алгоритм решения TSP, избегающего специальных кроссоверов и мутаций" Гоктурка Уколока. PDF здесь. Он дает обзор специальных операторов кроссовера для перестановок и предлагает умное представление перестановок, которое хорошо работает со стандартным кроссовером (т.е. Пересечение двух перестановок всегда создает две перестановки).
Ключевым понятием является представление перестановки в качестве ее последовательности инверсии, т.е. для каждого элемента i
, хранить в a[i]
, сколько элементов больше, чем i
слева от i
в перестановке. В отличие от прямого представления, единственное ограничение на a[i]
является локальным, т.е. a[i]
не может быть больше, чем N - i
. Это означает, что простой кроссовер двух действительных инверсионных последовательностей всегда создает две допустимые последовательности инверсии - нет необходимости в специальной обработке повторяющихся элементов.
Вместо того, чтобы использовать стандартную методику пересечения GA (как обозначенную MusiGenesis), лучше использовать заказал перекресток для проблемы с Traveling Salesman.
Обычный подход не работает так хорошо для TSP, потому что функция фитнеса очень чувствительна к относительным позициям разных городов на развитом маршруте, а не к их абсолютным позициям. Например, если вы посещали все европейские столицы, самый короткий маршрут не зависит от того, посещаете ли вы Братиславу 1, 2 или 9 место. Еще важнее то, что вы посещаете его сразу или сразу после посещения Вены, а не посещать Хельсинки, Афины и еще 6 других столиц между ними.
Конечно, поскольку mjv также указывает, традиционный перекресток будет также вводить дубликаты в вашем маршруте. Если один из родителей имеет Париж в позиции 2, а другой - Париж в позиции 14, перекресток может привести к одному развитому маршруту, который дважды посещает Париж (и пропускает другой город), а другой развитый маршрут, который его вообще не посещает. Упомянутый перекрестный генетический оператор не страдает от этой проблемы. Он сохраняет элементы и изменяет порядок.
Вот подход С# для того, что вы ищете.
Что касается интереса (или отсутствия) реализации перекрестного перехода, все это зависит от конкретной логики выбора, которую будет использовать реализация (и/или самой функции оценки, если, например, он включает в себя оценку скорости улучшения). Во многих случаях перекрестные операции будут "спасать из блока измельчения" некоторые решения, которые эффективны/оптимальны в области графика, но как-то "застревают" в других. Это не означает, что если общий алгоритм будет достаточно медленным и покрывает хороший процент пространства решений, то одни и те же решения могут быть не обнаружены заново, но перекрестное может также увеличить эти открытия (и/или позволить вам застрять в другие локальные минимумы;-))
Не связанный напрямую, но интересный интерес для любого, кто смотрит в GA, является оригинальным "конечным" экспериментом в GA оригинальный "конечный" эксперимент в GA профессором Олдерманом (известность RSA), который использовал фактические молекулы ДНК [в программу C - просто шутки] для решения связанной задачи графа - гамильтоновых графов.
Изменить. При повторном чтении вопроса я понимаю, почему вы спросили его или, точнее, , почему вам нужен ответ "Нет, вы не хотите перекрещивать" strong > ;-)
Ваш genonme напрямую привязан к самому графику (это не так неправильно, априори), но это создает препятствие, которое большинство перекрестных отключений не будет жизнеспособным, поскольку они могут иметь дублирующие узлы ( посещать один и тот же город дважды и более) и упускать узлы (не посетить некоторые города)... Кроме того, жизнеспособные кросс-кавы будут влиять на похожие графики и, следовательно, могут просто увеличивать затраты на поиск по сравнению с тем, что обнаружат мутации..
Hum... Тогда, может быть, перекрестный, в этой конкретной реализации не будет очень сильно помогать алгоритму (и, действительно, взять большую часть своего процессора для создания, тестирования и часто отбрасывать перекрестные потомки, CPU который лучше использовать, обеспечивая больше итераций и более медленную скорость охлаждения...). Если не! Вы найдете умный способ выполнения перекрестных операций; -)
Цель кроссовера - расширить эволюционное пространство поиска, объединив новые геномные комбинации.
Единственными реальными критериями, необходимыми для эволюционного процесса, является то, что продукт кроссовера содержит части обоих родителей и представляет собой действительный геном.
Только вы знаете правила действительности для своего алгоритма, поэтому вы можете указать только метод кроссовера, который будет работать (если вы не хотите делиться более подробными сведениями о правилах проверки для структуры генома).
Вот моя точная реализация так называемого метода "частично сопоставленного кроссовера" в 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;
}
Когда я был на первом курсе в своем университете, я делал некоторые вычисления (которые занимали около 30 страниц) о влиянии различных операторов GA на конвергенцию решения. Насколько я помню, кроссовер - не лучшее решение для TSP, более подходящим решением является мутация, которая является инвертированием подпоследовательности вершин.
Пример:
до: A BCDEF GH
после: A FEDCB GH
"Кроссовер" в генетических алгоритмах относится только к произвольному способу смешивания двух "генетических последовательностей", каждый из которых представляет собой конкретное решение проблемы (как последовательность соответствует решению зависит от вас). Так, например, скажем, у вас есть популяция, которая состоит из следующих двух последовательностей:
AAAAAAAAAA
BBBBBBBBBB
Один из способов рекомбинации этих двух "родительских" последовательностей состоит в случайном выборе точки пересечения (скажем, в позиции 3), приводящей к этим двум "дочерним" последовательностям:
AAABBBBBBB
BBBAAAAAAA
Или вы можете случайно выбрать две точки кроссовера (скажем, 3 и 8), что приведет к следующим двум последовательностям:
AAABBBBBAA
BBBAAAAABB
Для удовольствия и дополнительной изменчивости вы также можете ввести возможность случайных точечных мутаций:
AAABBBABAA
BBBAAAAABB
На самом деле не существует каких-либо жестких правил относительно того, как вы реализуете кроссовер в генетическом алгоритме, точно так же, как нет никаких жестких правил, регулирующих Эволюцию в биологическом мире. Что бы ни работало, работает.