1、实践题目
工作分配问题
2、问题描述
设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为cij 。 设计一个算法,对于给定的工作费用,为每一个人都分配1 件不同的工作,并使总费用达到最小。
输入格式:输入数据的第一行有1 个正整数n (1≤n≤20)。接下来的n行,每行n个数,表示工作费用。
输出格式:将计算出的最小总费用输出到屏幕。
输入样例:3
输出样例:9
3、算法描述(包括解空间,画出测试样例的解空间树,剪枝(约束函数或限界函数)方法描述)
(1)解空间
解空间为{x1,x2,x3,・・・・・・,xn},其中xi=1,2,3,4・・・,n,表示第i个人安排的工作号。
(2)解空间树:以n=3为例,解空间树如下:
(3)剪枝方法
(4)具体代码
1 #include<iostream> 2 using namespace std; 3 #define N 1000 4 int cost[N][N]; // 表示第i个人完成第j件工作需要的费用 5 int isC[N] = {0}; // 用于记录第n个工作是否完成,0表示未完成 6 int n; 7 int scost; // 表示总费用 8 9 void Backstrack(int i, int c) 10 { 11 if(c > scost) return; 12 if(i == n) { // 当最后一个人也分配好工作后判断总费用 13 if(c < scost) scost=c; 14 return; 15 } 16 for(int j=0;j<n;j++) { 17 if(isC[j]==0) { // 判断第j个工作是否已经完成,类似剪枝函数 18 isC[j]=1; 19 Backstrack(i+1, c+cost[i][j]); 20 isC[j]=0; // 回溯法 21 } 22 } 23 } 24 25 int main() 26 { 27 cin>>n; 28 for(int i=0;i<n;i++) { 29 for(int j=0;j<n;j++) { 30 cin>>cost[i][j]; 31 } 32 } 33 scost = N; // 给总费用设置一个很大的值 34 Backstrack(0,0); 35 // 第一个0表示从第一个人开始 ,第二个0表示当前需要的总费用 36 cout<<scost; 37 return 0; 38 }
4、心得体会(对本次实践收获及疑惑进行总结)
这次实践的过程中,可能是对回溯法还不是很了解,对剪枝函数或约束函数也不是很明白,所以在编程的过程中总是出现运行超时的问题,最后请教了同学,然后和结对编程小伙伴顺利地解决了问题。总体上对于回溯算法的理解还并不是很透彻,还需要多实践!