問題描述:某售貨員要到若干城市去推銷商品,已知各城市之間的路程,他要選定一條從駐地出發,經過每個城市一遍,最後回到住地的路線,使總的路程最短。
演算法描述:回溯法,排列樹。
假設起點為 1,演算法開始時 x = [1, 2, 3, ..., n]
x[1 : n]有兩重含義 x[1 : i]代表前 i 步按順序走過的城市, x[i + 1 : n]代表還未經過的城市。利用swap函式進行交換位置。
若i = n 時,處在排列樹的葉節點的父節點上,此時演算法檢查圖g是否存在一條從頂點x[n-1] 到頂點x[n] 有一條邊,和從頂點x[n] 到頂點x[1] 也有一條邊。若這兩條邊都存在,則發現了乙個旅行售貨員的迴路即:新旅行路線),演算法判斷這條迴路的費用是否優於已經找到的當前最優迴路的費用bestcost,若是,則更新當前最優值bestcost和當前最優解bestx。
若i < n 時,檢查x[i - 1]至x[i]之間是否存在一條邊, 若存在,則x [1 : i ] 構成了圖g的一條路徑,若路徑x[1: i] 的耗費小於當前最優解的耗費,則演算法進入排列樹下一層,否則剪掉相應的子樹。
bestc = float.max_value; // 初始化,設定最少花費為浮點型的最大值
bestx = v; // 最優路徑為v
cc = 0; // 當前花費為0
backtrack(2); // 從2開始搜尋,搜尋x[2:n]的全排列
return bestc; // 返回最優值
}private static void backtrack(int i)
// 最優值
bestc = cc + a[x[n - 1]][x[n]] + a[x[n]][1];
}} else }}
}// 對當前解路徑中的i和j進行替換
private static void swap(int x, int i, int j)
public static void main(string args)
}}// 執行結果:
// 最少花費:25.0
// 0->1->3->2->4
分支與限界 旅行售貨員問題
問題描述 演算法設計 演算法分析 應用舉例 實驗結果 類似於回溯法,也是一種在問題的解空間樹t上搜尋問題解的演算法。但在一般情況下,分支限界法與回溯法的求解目標不同。回溯法的求解目標是找出t中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的乙個解,或是在滿足約束條件的解中找出使某一...
旅行售貨員問題 回溯法
某售貨員要到若干城市去推銷商品,已知各城市之間的路程,他要選定一條從駐地出發,經過每個城市一遍,最後回到住地的路線,使總的路程最短。結果為 1 3 2 4 1 回溯法,序列樹,假設起點為 1。演算法開始時 x 1,2,3,n x 1 n 有兩重含義 x 1 i 代表前 i 步按順序走過的城市,x i...
回溯法 旅行售貨員問題
全排列回溯 include using namespace std const int max 0x3f3f3f 定義乙個最大值 const int noedge 1 兩個點之間沒有邊 int citynum 城市數 int edgenum 邊數 int currentcost 記錄當前的路程 in...