算法分析报告与设计课设.docx

上传人:b****5 文档编号:14298568 上传时间:2023-06-22 格式:DOCX 页数:18 大小:103.98KB
下载 相关 举报
算法分析报告与设计课设.docx_第1页
第1页 / 共18页
算法分析报告与设计课设.docx_第2页
第2页 / 共18页
算法分析报告与设计课设.docx_第3页
第3页 / 共18页
算法分析报告与设计课设.docx_第4页
第4页 / 共18页
算法分析报告与设计课设.docx_第5页
第5页 / 共18页
算法分析报告与设计课设.docx_第6页
第6页 / 共18页
算法分析报告与设计课设.docx_第7页
第7页 / 共18页
算法分析报告与设计课设.docx_第8页
第8页 / 共18页
算法分析报告与设计课设.docx_第9页
第9页 / 共18页
算法分析报告与设计课设.docx_第10页
第10页 / 共18页
算法分析报告与设计课设.docx_第11页
第11页 / 共18页
算法分析报告与设计课设.docx_第12页
第12页 / 共18页
算法分析报告与设计课设.docx_第13页
第13页 / 共18页
算法分析报告与设计课设.docx_第14页
第14页 / 共18页
算法分析报告与设计课设.docx_第15页
第15页 / 共18页
算法分析报告与设计课设.docx_第16页
第16页 / 共18页
算法分析报告与设计课设.docx_第17页
第17页 / 共18页
算法分析报告与设计课设.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

算法分析报告与设计课设.docx

《算法分析报告与设计课设.docx》由会员分享,可在线阅读,更多相关《算法分析报告与设计课设.docx(18页珍藏版)》请在冰点文库上搜索。

算法分析报告与设计课设.docx

算法分析报告与设计课设

成绩评定表

学生姓名

班级学号

专业

课程设计题目

动态规划-k乘积问题

回溯法-最小重量机器问题

 

 

组长签字:

成绩

 

日期

20年月日

 

课程设计任务书

学院

专业

学生姓名

班级学号

课程设计题目

动态规划-k乘积问题回溯法-最小重量机器问题

实践教学要求与任务:

要求:

1.巩固和加深对基本算法的理解和运用,提高综合运用课程知识进行算法设计与分析的能力。

2.培养学生自学参考书籍,查阅手册、和文献资料的能力。

3.通过实际课程设计,掌握利用动态规划算法、回溯法、分支限界法等算法的基本思想,并能运用这些方法设计算法并编写程序解决实际问题。

4.了解与课程有关的知识,能正确解释和分析实验结果。

任务:

按照算法设计方法和原理,设计算法,编写程序并分析结果,完成如下内容:

1.运用动态规划算法求解k乘积问题。

2.运用回溯法求解最小重量机器问题。

工作计划与进度安排:

第11周:

查阅资料。

掌握算法设计思想,进行算法设计。

第12周:

算法实现,调试程序并进行结果分析。

撰写课程设计报告,验收与答辩。

指导教师:

201年月日

专业负责人:

201年月日

学院教学副院长:

201年月日

 

摘要

为了满足人们对大数据量信息处理的渴望,为解决各种实际问题,计算机算法学得到了飞速的发展,线性规划、动态规划、贪心策略等一系列运筹学模型纷纷运用到计算机算法学中,产生了解决各种现实问题的有效算法。

虽然设计一个好的求解算法更像是一门艺术而不像是技术,但仍然存在一些行之有效的、能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。

一般情况下,为了获得较好的性能,必须对算法进行细致的调整。

但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。

动态规划的基本思想与分治法类似,也是将待求解的问题分解成若干份的子问题,先分别解决好子问题,然后从子问题中得到最终解。

但动态规划中的子问题往往不是相互独立的,而是彼此之间有影响,因为有些子问题可能要重复计算多次,所以利用动态规划使这些子问题只计算一次。

回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有可行的子树都已被搜索遍才结束。

而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。

这就是以深度优先的方式系统地搜索问题解的回溯算法,它适用于解决一些类似n皇后问题等求解方案问题,也可以解决一些最优化问题。

在做题时,有时会遇到这样一类题目,它的问题可以分解,但是又不能得出明确的动态规划或是递归解法,此时可以考虑用回溯法解决此类问题。

回溯法的优点在于其程序结构明确,可读性强,易于理解,而且通过对问题的分析可以大大提高运行效率。

 

关键词:

算法;动态规划;回溯法;

 

一、问题描述

1.1k乘积问题

设I是一个n位十进制整数。

如果将I划分为k段,则可得到k个整数。

这k个整数的乘积称为I的一个k乘积,试设计一个算法,对于给定的I和k,求出I的最大k乘积。

 

1.2最小重量机器问题

设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。

设wij是从供应商j处购得的部件i的重量,cij是相应的价格。

试设计一个算法,给出总价格不超过c的最小重量机器设计。

 

二、算法设计

1.对于给定的I和k,计算I的最大k乘积。

2.对于给定的机器部件重量和机器部件价格,计算总价格不超过d的最小重量机器设计。

 

三、设计原理

3.1动态规划

动态规划的基本思想是将问题分解为若干个小问题,解子问题,然后从子问题得到原问题的解。

设计动态规划法的步骤:

(1)找出最优解的性质,并刻画其结构特征;

(2)递归地定义最优值(写出动态规划方程);

(3)以自底向上的方式计算出最优值;

(4)根据计算最优值时得到的信息,构造一个最优解。

 

3.2回溯法

回溯法是一个既带有系统性又带有跳跃性的的搜索算法。

它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。

算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。

如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。

否则,进入该子树,继续按深度优先的策略进行搜索。

回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。

而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。

这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。

 

四、问题分析与设计

4.1k乘积问题

1.分析最优解的结构

为了方便起见,设I(s,t)是I的由s位开始的t位数字组成的十进制数,R(i,j)表示I(0,i)的j乘积。

第j段的起始位置为第w位,1<w≤j。

则有如下关系

R(i,j)=R(i,j-1)×I(w,j-w)

      要使R(i,j)最大,则R(i,j-1)也是最大,所以最大K乘积问题的最优解包含其子问题的最优解。

 

2.建立递归关系

设MaxI[i][j]表示I(0,i)的最大j乘积,则原问题的最优值为MaxI[n][k]。

当k=1时,MaxI[n][1]=I(0,n);

当k≠1时,可利用最优子结构性质计算MaxI[n][k], 若计算MaxI[n][k]的第k段的起始位置为第w位,1<w≤j,则有MaxI[n][k]=MaxI[w][k-1]×I(w,n-w)。

由于在计算时并不知道第k段的起始位置w,所以w还未定。

不过w的值只有n-k+2种可能,即k-1≤w≤n。

所以MaxI[n][k]可以递归地定义为

I(0,n)                               k=1

MaxI[n][k]=max  MaxI[w][k-1]×I(w,n-w)           k≠1

 MaxI[n][k]给出了最优值,同时还确定了计算最优的断开位置w,也就时说,对于这个w有 MaxI[n][k]=MaxI[w][k-1]×I(w,n-w)

若将对应于MaxI[n][k]的断开位置w记为demarcation[n][k]后,可递归地由 demarcation[n][k]构造相应的最优解。

 

4.2最小重量机器设计问题

1.用递归函数backtrack(i)来实现回溯法搜索排列树(形式参数i表示递归深度)。

①若cp>d,则为不可行解,剪去相应子树,返回到i-1层继续执行。

②若cw>=weight,则不是最优解,剪去相应子树,返回到i-1层继续执行。

③若i>n,则算法搜索到一个叶结点,用weight对最优解进行记录,返回到i-1层继续执行;

4用for循环对部件i从m个不同的供应商购得的情况进行选择(1≤j≤m)。

2.主函数调用一次backtrack

(1)即可完成整个回溯搜索过程,最终得到的weight即为所求最小总重量,p为该机器最小重量的价格。

五、算法实现

5.1k乘积问题

#include

#include

#include

#defineMAXN51

#defineMAXK10

//m[i][j]表示1~i十进制位分成j段所得的最大乘积

longm[MAXK][MAXN]={{0,0}};

//w[i][j]表示i~j十进制位所组成的十进制数

longw[MAXN][MAXN]={{0,0}};

intleaf[MAXN][MAXN]={{0,0}};

voidmaxdp(intn,intk,int*a)

{

inti,j,d;

longtemp,max;

for(i=1;i<=n;i++){//分成一段

m[i][1]=w[1][i];

}

for(i=2;i<=n;i++){//DP过程

for(j=2;j<=k;j++){

max=0;

for(d=1;d

//Testprintf("%d*%d=%ld\t-----------",m[d][j-1],w[d+1][i],m[d][j-1]*w[d+1][i]);

if((temp=m[d][j-1]*w[d+1][i])>max){

max=temp;

leaf[i][j]=d;

}

}

m[i][j]=max;

printf("\n");

}

}

printf("\n");

for(i=1;i<=n;i++){

for(j=1;j<=n;j++){

printf("%ld\t",m[i][j]);

}

printf("\n");

}

printf("\n");

for(i=1;i<=n;i++){

for(j=1;j<=n;j++){

printf("%ld\t",leaf[i][j]);

}

printf("\n");

}

}

 

//输出分割后的K个数

voidprint_foot(int*data,intn,intk)

{

intd,i;

intstack[256];

inttop=0;

inttmp;

tmp=n;

while((tmp=leaf[tmp][k])>0)

{

stack[top++]=tmp;

k--;

}

printf("Dividedsequence:

\n");

i=1;

while((--top)>=0)

{

tmp=stack[top];

for(;i<=tmp;i++)

{

printf("%d",data[i]);

}

printf("");

}

for(;i<=n;i++)

{

printf("%d",data[i]);

}

printf("\n");

}

intmain(void)

{

intn,k,i,j;

inta[MAXN]={0},la=0;

charc;

scanf("%d%d",&n,&k);//inputn,k

while((c=getchar())!

='#'){//readinteger

a[++la]=c-'0';

}

for(i=1;i<=n;i++){

w[i][i]=a[i];

for(j=i+1;j<=n;j++)

w[i][j]=w[i][j-1]*10+a[j];

}

for(i=1;i<=n;i++){

for(j=1;j<=n;j++){

printf("%ld\t",w[i][j]);

}

printf("\n");

}

maxdp(n,k,a);

printf("%ld\n",m[n][k]);

print_foot(a,n,k);

return0;

}

5.2最小重量机器问题

/*头文件最小重量机器设计问题.h*/

#ifndefKNAP_H

#defineKNAP_H

#include

#include

usingnamespacestd;

classMachine//机器类

{

public:

Machine(char*in,char*out);//构造函数

~Machine();//析构函数

voidSolve();//输出结果到文件

protected:

voidSearch(inti,ints,intl,int*e);//从第i个部件开始递归搜索

voidPrint();//输出结果

private:

intn;//部件个数

intm;//供应商个数

intd;//价格上限

int**w;//部件重量

int**c;//部件价格

intmin;//最小重量

int*plan;//选购的部件

ofstreamfout;//输出结果文件

};

#endif

/*函数实现文件最小重量机器设计问题.cpp*/

#include"最小重量机器设计问题.h"

Machine:

:

Machine(char*in,char*out):

fout(out)

{

ifstreamfin(in);

if(!

fin)

{

cerr<<"文件"<

"<

exit

(1);

}

fin>>n>>m>>d;//初始化部件个数n,供应商数m,价格限制d

w=newint*[n+1];

for(inti=1;i<=n;i++)

{

w[i]=newint[m+1];

for(intj=1;j<=m;j++)

fin>>w[i][j];//初始化部件重量

}

c=newint*[n+1];

for(inti=1;i<=n;i++)

{

c[i]=newint[n+1];

for(intj=1;j<=m;j++)

fin>>c[i][j];//初始化部件价格

}

fin.close();

min=INT_MAX;//初始化最小重量

plan=newint[n+1];

for(inti=1;i<=n;i++)

plan[i]=0;//初始化选购计划

if(!

fout)

{

cerr<<"文件"<

"<

exit

(1);

}

}

Machine:

:

~Machine()

{

if(fout)

fout.close();

for(inti=1;i<=n;i++)

{

if(w[i])

delete[]w[i];

if(c[i])

delete[]c[i];

}

if(w)

delete[]w;

if(c)

delete[]c;

}

voidMachine:

:

Solve()

{

int*e;

e=newint[n+1];

for(inti=1;i<=n;i++)

e[i]=0;

Search(1,0,0,e);//第一个零件开始搜索,初始重量和价格是0

Print();//输出函数

}

voidMachine:

:

Search(inti,ints,intl,int*e)

{

if(i==n+1)//选购完毕

{

if(s

{

min=s;//更新重量最小值

for(inti=1;i<=n;i++)

plan[i]=e[i];//更新选购计划

}

return;

}

if(s>min)//重量超过min,剪枝

return;

for(intj=1;j<=m;j++)

{

e[i]=j;

s+=w[i][j];//加上第i部件由j供应商提供的重量

l+=c[i][j];//加上第i部件由j供应商提供的价格

Search(i+1,s,l,e);//递归选购下一个部件

s-=w[i][j];

l-=c[i][j];

}

}

voidMachine:

:

Print()

{

fout<

for(inti=1;i<=n;i++)

fout<

}

/*主函数文件test.cpp*/

#include"最小重量机器设计问题.h"

intmain()

{

char*in="input.txt";//输入文件

char*out="output.txt";//输出文件

Machinemachine(in,out);//文件初始化机器

machine.Solve();//回溯法求解

return0;

}

六、结果分析

1.

 

注释:

输入一个三位数,将其分为两段,使这两端乘积最大。

当这个三位数为521时,5与21相乘积最大,为105

 

2.

 

总结

算法是编程最终的部分,想要把程序写的好,就要用好的算法。

不同的问题有不同的算法模型,同一个问题也可能有不同的算法描述。

每种算是都有自己的时间复杂度和空间复杂度。

并不是说时间复杂度低或者空间复杂度就是一个好的算法,这要看用来解决什么问题,还编程的环境结合起来评价的。

所以学编程的人应该把算法学好,这样才有利于编程,也有利于想出更好的算法来解决现实中的问题。

参考文献

[1]王晓东.计算机算法设计与分析(第4版).北京.电子工业出版社.2012.2

[2]严蔚敏.数据结构.北京.清华大学出版社.2009

[3]谭浩强.C语言程序设计(第3版).北京.清华大学出版社.2012

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2