Сохранение оптимального пути с помощью рекурсивного отслеживания

Я частично решил проблема на судье UVA (см. код ниже), с рекурсивным возвратом / динамическим программированием и битовой маскировкой.

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

Проблема — проблема коммивояжера, в основном проблема заключается в следующем:

Дано n координаты, найдите кратчайший путь между всеми этими координатами.

#include<iostream>
#include<cmath>
#include<climits>
#include<cstdio>
using namespace std;

#define MAX_N 10

struct Computer{
double x;
double y;
};

Computer computers[MAX_N];
double dist[MAX_N][MAX_N];
double DP[MAX_N][1 << MAX_N];

size_t n;

double d(Computer a, Computer b) {
return sqrt(pow((a.x - b.x), 2.0) + pow((a.y - b.y), 2.0)) + 16.0;
}

double recurse(int i, int switched)
{
if(switched == (1 << n) - 1) return 0;
if(DP[i][switched] != 0) return DP[i][switched];

double local_min = INT_MAX;
for(int j = 0; j < n; j++)
if(i != j && !(switched & (1 << j)))
local_min = min(dist[i][j] + recurse(j, switched | (1 << j)), local_min);

return DP[i][switched] = local_min;
}

int main()
{
for(unsigned int p = 1; cin >> n; p++) {
if(n == 0) return 0;
memset(DP, 0, sizeof DP);

for(size_t i = 0; i < n; ++i) {
Computer c; cin >> c.x >> c.y;
computers[i] = c;
}

for(size_t i = 0; i < n; ++i) for(size_t j = 0; j < n; ++j)
dist[i][j] = d(computers[i], computers[j]);

printf("%d: %.2f\n", p, recurse(0, 1));
}
}

1

Решение

Распространенный способ хранения пути — это отслеживание дополнительной карты, в которой хранится узел, который использовался для поиска пути к текущей точке. Найдя оптимальный маршрут до конечного узла, вы можете запрашивать эту карту, пока не вернетесь к начальному узлу.

1

Другие решения

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

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

1