您的当前位置:首页正文

实验5 回溯算法

2021-12-15 来源:好走旅游网
 最小成本的回溯算法问题

班级 通信一班 学号14082300943姓名 张博 成绩 分

一、设计目的

1.掌握回溯法解题的基本思想; 2.掌握回溯算法的设计方法;

3.针对子集和数问题,熟练掌握回溯递归算法、迭代算法的设计与实现。

二、设计内容

分派问题: 给n个人分派n件作业, 把工作j分派给第i个人的成本为cost(i, j), 设计、编程、测试回溯算法, 在给每个人分派一件不同工作的情况下使得总成本最小。 1.阐述用回溯法求解的状态空间树结构:

画出部分树,说明节点、边、到根节点的路径的意义,给

出答案节点的定义。

2.阐述用回溯法求解的基本思想:

设计并说明规范函数,扼要阐述搜索过程。 3.画出搜索过程的主要流程图。 4.说明输入数据的表示方法、主要的数据变量、主要的函数功能。 5.写出各函数的伪C语言代码。

三、设计数据

假设有三个人完成不同的三个作业,他们对完成不同的作业所需 要的成本是不同的,集体情况如下表所示:

工人 作业 1 成本:1 成本:3 成本:4 2 成本:2 成本:1 成本:5 3 成本:3 成本:4 成本:1 1 2 3 四、设计结果

1.设计的状态空间树结构: 工人1 作业:1 成本:1 1 作业:3 作业:2 成本:3 成本:4 工人2 作业:2 成本:1 2 7 作业:3 成本:5 作业:1 成本:2 作业:3 成本:5 作业:1 成本:2 12 作业:2 成本:1 工人3 3 5 作业:2 成本:4 8 作业:3 成本:1 10 作业:1 成本:3 13 作业:2 成本:4 15 作业:1 成本:3 作业: 3 成本:1 4 成本: 3 6 10 9

11 11 14 16 6 10 8 上图中前一、二、三层分别为工人1、2、3,工人1可以先有3

中作业选择,然后工人2在剩下的2个作业中选1个作业,剩下的自然就是工人3要做的作业。图中已经在标记处标明了每个工人所做的作业及其所用成本,以及最后每种情况所需的成本的结果。

2.阐述用回溯法求解的基本思想:

(1)规范函数

int Place(int k) //Place判断在第 k 个人是否可以做x[k]的事 {int i;

for(i = 1; i < k; i++) if(x[i]==x[k]) return 0; return 1;}

(2)设计一个成本的最大值minsum,然后在每次遍历工人作业的成本,把较小的成本覆盖minsum,直到最后把最小的成本来找到。 (3)在遍历每个工人所作作业的成本的时候都和minsum进行比较,如果当时的成本已经比minsum大了就没有必要继续往下走了,就返回到上一个节点,继续另外的情况。这便是回溯算法的本质。 3.画出搜索过程的主要流程图。

当前成本:2 1 当前成本:0 2 当前成本:1 7 当前成本:3 12 当前成本:4 3 4 5 当前成本:6 1 当前成本:2 1 当前成本:5 当前成本:3 最小成本:3

4.说明输入数据的表示方法、主要的数据变量、主要的函数功能。 int n//表示有n个工人和n个作业

int sumcost//存放成本总和 int minsum//存放最小成本

int cost[i][j]//表示工人i做作业j做需要的成本。

int Place(int k) //Place判断在第 k 个人是否可以做x[k]的事

void NQueens(int k, int sumcost)//遍历每种情况,比较每种情况下的成本,得出最小成本。 5.写出各函数的伪C语言代码。

int Place(int k) //Place判断在第 k 个人是否可以做x[k]的事 { int i;

for(i = 1; i < k; i++)

if(x[i]==x[k]) return 0; return 1; }

void NQueens(int k, int sumcost)

{ if(sumcost > mincost) return ;x[k] = 0; while(1) { x[k]++;

while((x[k]<=n)&&(!Place(k))) x[k]=x[k]+1; if(x[k] <= n) {

sumcost += cost[k][x[k]]; if(k < n)

NQueens(k+1, sumcost);

else {

if(sumcost < mincost) mincost = sumcost;

}

sumcost -= cost[k][x[k]]; }

else return ;

} }

6.运行结果

程序时用C代码写的,并在VC++6.0上面运行成功。

五、设计总结与讨论

通过此次算法设计对回溯算法有了更进一步的理解,对之前的状态空间树很模糊,不知道怎么弄,但是通过实验我有了很好的理解。在这过程中,我又仔细阅读了教科书,以及回忆老师上课所讲解的知识,把回溯算法的思路进行了理清,最后用C代码实现了它,本次的感悟是只要我们学生愿意花时间去思考,就能学到我们的知识,并且实践它。

六、程序代码

#include

int cost[100][100],x[100]; int mincost,n;

int Place(int k) //Place判断在第 k 个人是否可以做x[k]的事 { int i;

for(i = 1; i < k; i++) if(x[i]==x[k]) return 0; return 1;}

void NQueens(int k, int sumcost)//搜索最小成本函数 { if(sumcost > mincost) return ;x[k] = 0; while(1){ x[k]++;

while((x[k]<=n)&&(!Place(k))) x[k]=x[k]+1; if(x[k] <= n)

{sumcost += cost[k][x[k]]; if(k < n)

NQueens(k+1, sumcost); else

{if(sumcost < mincost) mincost = sumcost;} sumcost -= cost[k][x[k]];}

Else return ; } }

int main() {

int i,j;

mincost = 0x7fffffff; printf(\"输入n:\"); scanf(\"%d\

printf(\"依次输入第i个人做第j作业的成本:\\n\"); for(i=1;i<=n;i++) for(j=1;j<=n;j++)

scanf(\"%d\

printf(\"\\n以上从键盘输入的数组的意思是:行代表人,列代表作业的成本\\n\");

printf(\"第i行第j列表示:工人i做作业j所需要的成本!\\n\\n\");

NQueens(1,0);

printf(\"最小总成本为: %d\\n\

printf(\"\\n\\n感谢谢老师!算法设计很有趣!!08通信一班 张博 14082300943\\n\"); return 0;

}

因篇幅问题不能全部显示,请点此查看更多更全内容