第5章上机实践报告

1、实践题目

工作分配问题

2、问题描述

设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为cij 。 设计一个算法,对于给定的工作费用,为每一个人都分配1 件不同的工作,并使总费用达到最小。

输入格式:输入数据的第一行有1 个正整数n (1≤n≤20)。接下来的n行,每行n个数,表示工作费用。

输出格式:将计算出的最小总费用输出到屏幕。

输入样例:3

                 10 2 3

                  2 3 4

                  3 4 5

输出样例:9

3、算法描述(包括解空间,画出测试样例的解空间树,剪枝(约束函数或限界函数)方法描述)

(1)解空间

解空间为{x1,x2,x3,······,xn},其中xi=1,2,3,4···,n,表示第i个人安排的工作号。

(2)解空间树:以测试样例为例,解空间树如下:

(3)剪枝方法

1、每个工作是否已被分配,如已被分配,则不再分配给下一个人。

2、如果判断当前费用c已经大于之前算 

(4)代码实现

 1 #include <iostream>
 2 using namespace std;
 3 int n;//工作数量
 4 int a[21][21];//工作费用
 5 int flag[21];//标记是否已经分配过
 6 int bestc = 0;//最少费用 
 7  
 8 void backtrack(int i,int c){
 9     if(i>n&&c<bestc){
10         bestc = c;
11         return;
12     }
13     if(c<bestc)
14         for(int j=1;j<=n;j++){
15             if(flag[j]==0){
16                 flag[j]=1;
17                 backtrack(i+1,c+a[i][j]);
18                 flag[j]=0;
19             }
20         }
21     }
22 
23 
24 int main(){
25     cin>>n;
26     for(int i=1;i<=n;i++){
27         for(int j=1;j<=n;j++){
28             cin>>a[i][j];
29         }
30         flag[i]=0;//初始都没有分配工作 
31         bestc += a[i][i];//初始费用初始化为对角线之和 
32         
33     }
34     backtrack(1,0);
35     cout<<bestc;
36     return 0;
37     
38 }

4、心得体会

(1)本次实践过程让我加深了对回溯算法的理解,特别是回溯的过程和限界函数,可能在上课的时候听老师讲是有点似懂非懂的,但是通过上机实践之后能很快发现自己不懂的地方在哪里,能比较快地发现自己的问题。

(2)不管是0-1背包还是这道工作分配,我觉得确定解空间树还是比较简单的,比较难的是回溯的过程还有限界函数的确定,需要在对解空间树的理解的基础上进行分析。还有就是不能死套框架,像我们在解工作分配这道题的时候,一开始觉得它与旅行售货员问题很像,所以就想套用旅行售货员的框架,结果就出了一点小问题,后来才发现这道题是没有旅行售货员那么复杂的,所以在解题的时候要懂得灵活应用,而不是一味地套框架。

猜你喜欢

转载自www.cnblogs.com/huangroumin/p/10164132.html
今日推荐