Вы ищете перестановки всех городов, в которых установлен первый город.Если число городов фиксировано, вы можете записать, что вложенное меню for
зацикливается, но это быстро становится громоздким.
Вместо этого рекурсивно переставляйте массив:
- Создайте массив
path
порядка посещения городов;начать с {0, ..., N - 1}. - Выберите начальный индекс.Если вам нужны все возможные начальные точки, выберите 0. Здесь первый город фиксирован, поэтому начните с индекса 1, поскольку
path[1]
- это первая запись, которая должна измениться. - Вызовите функцию перестановки:
- Теперь, если есть еще города, которые нужно переставить, поменяйте каждый из них по очереди на следующую позицию, вызовите функцию перестановки со следующим индексом, а затем поменяйте местами город назад.Во время повторения следите за текущим расстоянием.
- Если городов больше нет, вы достигли конца списка.Напечатайте путь и расстояние или все, что вы хотите сделать, и больше ничего не делайте.
Вот как это может выглядеть в коде:
#include <stdlib.h>
#include <stdio.h>
enum {
N = 4 // number of cities
};
const int city[N][N] = {
{0, 2, 5, 5},
{2, 0, 3, 4},
{5, 3, 0, 6},
{5, 4, 6, 0},
};
/*
* Swap array elements at indices i and j
*/
void swap(int a[], int i, int j)
{
if (i != j) {
int swap = a[i]; a[i] = a[j]; a[j] = swap;
}
}
/*
* Permute the subarray of length n, starting at index i
*/
void perm(int path[], int i, int n, int weight)
{
int j;
if (i == n) { // path is exhausted:
for (j = 0; j < n; j++) { // print path and distance
printf("%c ", 'A' + path[j]);
}
printf("-> %d\n", weight);
} else { // more cities to visit:
for (j = i; j < n; j++) { // pick each of them as ...
int w = 0; // ... destination
if (i > 0) { // determine distance ...
w = city[path[i - 1]][path[j]]; // ... from prev. city,
} // ... if any
swap(path, i, j); // swap city in;
perm(path, i + 1, n, weight + w); // recurse;
swap(path, i, j); // swap city back
}
}
}
int main()
{
int path[N];
int i;
for (i = 0; i < N; i++) path[i] = i; // initial path
perm(path, 1, N, 0);
return 0;
}