全排列與回溯法解旅行商問題

2021-07-13 01:45:32 字數 3000 閱讀 7167

雖然說全排列好像很簡單,但真的當用程式來生成時還一時不知道怎麼辦,但是我覺得窮舉法是很多演算法的基礎,比如回溯法,排序等,我會以旅行商問題來說明全排列,只需一次就會了。

回溯法的本質也是搜尋,只是加上了約束條件,使搜尋的次數減少許多,我們把約束條件和目標函式的邊界稱為剪枝策略。

對於旅行商這個問題,說的是乙個商人想從乙個城市出發,不重複地走遍所有城市然後回到起點,每個城市間有不同的旅行費用,求花最少的錢走完?

典型的乙個圖的儲存結構,如下例子:

我採用簡單的二維矩陣儲存結構,接下來:

我會給出窮舉的演算法,然後加上約束條件,最後進行對比。

窮舉次序列的本質是全排列,採用遞迴生成,列印全過程:

仔細的看**就好,注釋很詳細,全排列的精髓就在那了:

#include 

using

namespace

std;

int *x;//城市編號陣列

int *bestx;//路線

int w = 0;//過渡變數

int bestw = int32_max;//最優的費用

void tsp(int **a, int n, int s);

int main()

bestx = new

int[n];

a = new

int*[n];

for (int i = 0; i < n; i++)

//輸入費用矩陣表示圖

for (int i = 0; i < n; i++)

}tsp(a, n, 1);//傳1表示只搜從0開始的全排,傳0表示所有全排

cout

<< "最優的是:"

<< bestw << endl;

for (int i = 0; i < n; i++)

deletea;

deletex;

deletebestx;

return0;}

void tsp(int **a, int n, int s)

else

}cout

<< "w:"

<< w << endl;

if (bestw > w)

}else }}

執行結果如下:

5

0 3 3 2 6

3 0 7 3 2

3 7 0 2 5

2 3 2 0 3

6 2 5 3 0

bestx: 0 1 2 3 4 w

:21bestx: 0 1 2 4 3 w

:20bestx: 0 1 3 2 4 w

:19bestx: 0 1 3 4 2 w

:17bestx: 0 1 4 3 2 w

:13bestx: 0 1 4 2 3 w

:14bestx: 0 2 1 3 4 w

:22bestx: 0 2 1 4 3 w

:17bestx: 0 2 3 1 4 w

:16bestx: 0 2 3 4 1 w

:13bestx: 0 2 4 3 1 w

:17bestx: 0 2 4 1 3 w

:15bestx: 0 3 2 1 4 w

:19bestx: 0 3 2 4 1 w

:14bestx: 0 3 1 2 4 w

:23bestx: 0 3 1 4 2 w

:15bestx: 0 3 4 1 2 w

:17bestx: 0 3 4 2 1 w

:20bestx: 0 4 2 3 1 w

:19bestx: 0 4 2 1 3 w

:23bestx: 0 4 3 2 1 w

:21bestx: 0 4 3 1 2 w

:22bestx: 0 4 1 3 2 w

:16bestx: 0 4 1 2 3 w

:19最優的是:13

請按任意鍵繼續. . .

現在,我們加上約束條件:

#include "stdafx.h"

#include

using

namespace

std;

int *x;//城市編號陣列

int *bestx;//最好的路線

int bestw = 0;//最優的費用

int cc = 0;//過渡變數cost

void tsp(int **a, int n, int s);

int main()

bestx = new

int[n];

a = new

int*[n];

for (int i = 0; i < n; i++)

//輸入費用矩陣表示圖

for (int i = 0; i < n; i++)

}tsp(a, n, 1);

cout

<< "最優的是:"

<< bestw << endl;

for (int i = 0; i < n; i++)

deletea;

deletex;

deletebestx;

return0;}

void tsp(int **a, int n, int s)

bestw = cc + a[x[n - 1]][x[0]];

cout

<< "bestw:"

<< bestw << endl;}}

else }}

}

再來看執行結果:

可以看出約束條件還是很有用的。

全排列的大體框架都差不多,操作都在s==n裡。

回溯法 旅行商問題

給定無向圖g n,e 含有n個結點,m條邊。現在有以下定義 有乙個商人從1號結點出發,希望經過每個結點一次回到起點,並且他希望走權值最小的一條路徑。輸入第一行2個整數n,m 接下來m行,每行三個數,u,v,w表示u,v結點有一條權值為w的無向邊。如果不存在這種路徑,列印 1 否則列印兩行。第一行乙個...

旅行商問題(貪婪法)

h greedytsp.h created on 2011 7 12 author 哈哈 ifndef greedytsp h define greedytsp h include using namespace std include include void printstate vector ...

暴力法解決旅行商問題

找出一條n個給定的城市間的最短路徑,使得我們在回到出發的城市之前,都經過了每個城市有且僅有一次。下圖表示4個城市及其路徑的一張圖。按照暴力法可以將所有的路線列出來,然後找出最佳的路線。a b c d a distance 2 8 1 7 18 a b d c a distance 2 3 1 5 1...