算法第五章实践报告
?
1、實踐題目 :工作分配問題
?
2、問題描述
設有n件工作分配給n個人。將工作i分配給第j個人所需的費用為cij 。 設計一個算法,對于給定的工作費用,為每一個人都分配1 件不同的工作,并使總費用達到最小。
輸入:輸入數據的第一行有1 個正整數n (1≤n≤20)。接下來的n行,每行n個數,表示工作費用。
輸出:將計算出的最小總費用輸出到屏幕。
?
3、算法描述(包括解空間,畫出測試樣例的解空間樹,剪枝(約束函數或限界函數)方法描述)
1 #include<iostream> 2 using namespace std; 3 4 int minExp =0 ; //初始化當前費用和最小費用為0 5 int n ; //n個人n件工作 6 int a[50][50] ; 7 int x[50] ; 8 9 10 void backtrace(int i , int cexp){ //第i個工作 11 12 13 if(i > n ){ 14 if(cexp < minExp) minExp = cexp; 15 return ; 16 } 17 if(cexp < minExp){ 18 for(int j = 1 ; j <= n ; j++){ 19 if(x[j] == 0){ //第j個人是否有工作 20 x[j] = 1 ; 21 backtrace(i+1 , cexp + a[i][j]) ; 22 x[j] = 0 ; 23 } 24 } 25 } 26 } 27 int main() 28 { 29 cin >> n ; 30 31 for(int i=1 ; i<=n ; i++){ 32 for(int j=1 ; j<=n ; j++){ 33 cin >> a[i][j] ; //第i個人做第j份工作的費用 34 x[j] = 0 ; 35 } 36 minExp+=a[i][i] ; 37 } 38 39 backtrace(1,0) ; //從第一個人開始遍歷 40 cout << minExp ; 41 42 return 0; 43 }?解空間為:{(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)}
?約束函數:
x[j] == 0即第j個人是否有工作 限界函數:
cexp < minExp 即當前費用小于最小費用
?
4、心得體會(對本次實踐收獲及疑惑進行總結)
剛開始做這道題想用數組交換元素的方法做,但是發現結果不對,其實這道題可以這樣想:設置一個數組x[]來記錄每個人是否有工作,每分配一份工作就從頭遍歷一次詢問該元素i的x[i]是否為0,是則將該工作分配給他,再通過回溯來搜索出所有的情況,出來的代碼比較簡單。第二個要注意的是最小工作費用的初始化問題,由于遍歷解空間樹時第一條路徑是(1,2,3)所以最小工作費用可以初始化為a[1][1]+a[2][2]+a[3][3]。這道題的解空間樹屬于排列樹,也讓我更加熟練掌握回溯法中排列樹的算法思路和框架。
轉載于:https://www.cnblogs.com/hwy1003213/p/10170586.html
總結
- 上一篇: JAVA连接MYSQL数据库
- 下一篇: 界面设计