算法分析与设计课设word版本Word格式文档下载.docx

上传人:b****6 文档编号:21843376 上传时间:2023-02-01 格式:DOCX 页数:14 大小:104.61KB
下载 相关 举报
算法分析与设计课设word版本Word格式文档下载.docx_第1页
第1页 / 共14页
算法分析与设计课设word版本Word格式文档下载.docx_第2页
第2页 / 共14页
算法分析与设计课设word版本Word格式文档下载.docx_第3页
第3页 / 共14页
算法分析与设计课设word版本Word格式文档下载.docx_第4页
第4页 / 共14页
算法分析与设计课设word版本Word格式文档下载.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

算法分析与设计课设word版本Word格式文档下载.docx

《算法分析与设计课设word版本Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法分析与设计课设word版本Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。

算法分析与设计课设word版本Word格式文档下载.docx

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)

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

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

(4)(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<

stdio.h>

string.h>

stdlib.h>

#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;

=n;

i++){//DP过程

for(j=2;

j<

=k;

j++){

max=0;

for(d=1;

d<

i;

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("

i<

=n;

i++){

for(j=1;

j<

j++){

%ld\t"

m[i][j]);

printf("

leaf[i][j]);

}

//输出分割后的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--;

Dividedsequence:

i=1;

while((--top)>

=0)

tmp=stack[top];

for(;

i<

=tmp;

i++)

{

%d"

data[i]);

"

for(;

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++){

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

for(j=i+1;

j++)

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

w[i][j]);

}

maxdp(n,k,a);

%ld\n"

m[n][k]);

print_foot(a,n,k);

return0;

5.2最小重量机器问题

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

#ifndefKNAP_H

#defineKNAP_H

#include<

iostream>

fstream>

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<

<

文件"

<

in<

无法打开!

"

endl;

exit

(1);

fin>

>

n>

m>

d;

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

w=newint*[n+1];

for(inti=1;

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

for(intj=1;

j<

=m;

fin>

w[i][j];

//初始化部件重量

c=newint*[n+1];

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

c[i][j];

//初始化部件价格

fin.close();

min=INT_MAX;

//初始化最小重量

plan=newint[n+1];

plan[i]=0;

//初始化选购计划

fout)

out<

~Machine()

if(fout)

fout.close();

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];

e[i]=0;

Search(1,0,0,e);

//第一个零件开始搜索,初始重量和价格是0

Print();

//输出函数

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

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

if(s<

min&

&

l<

=d)//找到一个更优解

min=s;

//更新重量最小值

for(inti=1;

plan[i]=e[i];

//更新选购计划

return;

if(s>

min)//重量超过min,剪枝

for(intj=1;

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];

Print()

fout<

min<

fout<

plan[i]<

'

;

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

intmain()

char*in="

input.txt"

//输入文件

char*out="

output.txt"

//输出文件

Machinemachine(in,out);

//文件初始化机器

machine.Solve();

//回溯法求解

六、结果分析

1.

注释:

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

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

2.

总结

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

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

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

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

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

参考文献

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

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

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

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

当前位置:首页 > 工程科技 > 环境科学食品科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1