- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
分派问题回溯解法
设计五
分派问题的回溯解法
班级通信08-2BF 学号14082300929 姓名杨福 成绩 分
设计目的
1.掌握回溯法解题的基本思想;
2.掌握回溯算法的设计方法;
3.针对子集和数问题,熟练掌握回溯递归算法、迭代算法的设计与实现。
设计内容
任务描述
1)分派问题简介
假设有n 个人的成本是w,工作效率p和完成工作的总成本M均为已知正数,这个问题要求选择出成本的一个子集,使得,且极小化,这n个x构成一个取0/1值的向量。
2)设计任务简介
分派问题: 给n个人分派n件工作, 把工作j分派给第i个人的成本为cost(i, j), 设计、编程、测试回溯算法, 在给每个人分派一件不同工作的情况下使得总成本最小。
阐述用回溯法求解的状态空间树结构:
画出部分树,说明节点、边、到根节点的路径的意义,给出答案节点的定义。
阐述用回溯法求解的基本思想:
设计并说明规范函数,扼要阐述搜索过程。
画出搜索过程的主要流程图。
说明输入数据的表示方法、主要的数据变量、主要的函数功能。
5)写出函数的为C语言代码
分派问题的表示方案
功能:用回溯法得可行解并选最优解。
树中的节点:求解过程的一个状态
树中的边:标示 xi 的一个可能的值
解向量: 由根节点到任意叶节点的路径定义
解空间:由根节点到所有叶节点的路径定义
答案节点:求出最优解的状态
回溯法求解的基本思想:
基本任务:
1) 根据问题特点设计状态空间树
2) 逐个地生成问题状态
3) 确定问题状态是否是解状态
4) 确定解状态是否是答案状态
规范函数:
int Place(int k)
{ int i;
for(i=0; ik; i++)
if(x[i]==x[k])
return 0;
return 1;
}
搜索过程:
先深度搜索记录搜索的各节点的成本和s再与os比较如果s比os小,将s赋值给os,并将搜索到的节点赋给y[i],当深度搜索结束,返回上一个节点继续搜索;如此循环,直到搜索搜索结束。Y[i]即为所求的答案节点。
主要数据类型与变量
int os; // 记录任务分派过程中当前最小成本;
int s; // 表示在分派任务过程中每成功分派一个累计成本;
int x[n]; // 记录每成功分派任务给的人员;
int y[n]; // 记录分派任务时任务分派所给的人员所得最小成本;
int Place(int k) //功能: 规范函数,判断任务k是否可以分给x[k]号人员。
void work() //功能:用回溯法得可行解并选最优解。
算法或程序模块
#includestdio.h
#define n 4
int c[n][n]={4,1,2,1,2,3,1,3,4,2,1,5,4,2,1,2};
int x[n],y[n];
int os;
int Place(int k) //规范函数
{ int i;
for(i=0; ik; i++)
if(x[i]==x[k]) return 0;
return 1;
}
void work() //求最优解函数
{ int k,s;os=1000; k=0; x[k]=-1;
while(k=0)
{ x[k]=x[k]+1;
while((x[k]n) (!Place(k))) x[k]=x[k]+1;//求可行解
if(x[k]n)
{ if(kn-1) { k=k+1; x[k]=-1; }
else
{ s=0; for(int i=0;in;i++)
{ s+=c[i][x[i]];
}
if(sos) //判断可行解是否为最优解,是就记录在y[n]数组里
{
for(int i=0;in;i++)
{ y[i]=x[i];
os=s;
}
}
}
}
else k=k-1; //如果不是可行解就返回上一个节点
}
}
void main()
{ int i,j;
for(i=0;in;i++)
{for(j=0;jn;j++)
printf( %
文档评论(0)