Понятие исчерпывающего перебора. Решение задачи коммивояжера. - EcsFlash/DataTypes GitHub Wiki

Исчерпывающий перебор представляет собой подход к комбинаторным задачам с позиции грубой силы. Он предполагает генерацию всех возможных элементов из области определения задачи, выбор тех из них, и последующий поиск нужного элемента(например, оптимизирующего значение целевой ф-ии задачи). Заметим, что, хотя идея исчерпывающего перебора весьма проста, ее реализация обычно требует алгоритма для генерации определенных комбинаторных объектов.

Задача Коммивояжера

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

int naiveTSP(int start) {
	start -= std_offset;
	int sum = INT_MAX;
	set<int> wasIn{ start };
	for (int i = 0; i < kernel.size(); i++) {
		if (kernel[start][i] != 0) {
			int temp = ntsp(i, wasIn, start) + kernel[start][i]; //длина пути от непосещеной вершины до конца + длина от текущей до непосещенной
			if (temp < sum) {
				sum = temp;
			}
		}
	}
	return sum;
}
int ntsp(int start, set<int> wasIn, int realStart) {
	if ( kernel.size() - wasIn.size() == 1) {
		return kernel[start][realStart];
	}
	wasIn.insert(start);
	for (int i = 0; i < kernel.size(); i++) {
		if (wasIn.count(i) == 0 && kernel[start][i] != 0) {
			return ntsp(i, wasIn, realStart) + kernel[start][i];//длина пути от непосещеной вершины до конца + длина от текущей до непосещенной
		}
	}
}

Рассмотрим пример: image

Начнем путь с вершины под номером 1. Из нее мы можем попасть в вершины 2, 3, 4. Соответственно рекурсивно продолжаем строить наши пути. Из вершины 2 мы можем попасть в вершины 3 и 4. А из вершины 3 только в 4. Когда дойдем до вершины 4, непосещенных на данном маршруте вершин не останется. Соответственно необходимо просто вернуться в начальную. image То есть на каждом шаге алгоритм выстраивает маршрут, попутно вычисляя его длину.

⚠️ **GitHub.com Fallback** ⚠️