算法设计小论文

0-1背包问题

学 院 计算机科学技术学院
专业班级
年 级
学 号
姓 名 xxx
日 期 xxxx年xx月xx日

目录
摘要 1
引言 1

  1. 问题描述 2
  2. 算法设计与分析 2
    2.1算法分析 2
    2.2算法设计 2
  3. 程序编码与调试分析 4
    3.1程序编码 4
    3.2调试分析 5
  4. 测试结果 6
  5. 自学知识 7
    6.总结 8
    7.参考文献 9

摘要
算法是一个系列解决问题的清晰指令,即在有限时间内能够对一定规范的输入,能够得到所需要的输出。如果一个算法本身是有缺陷的!那么他往往不是这个问题的最佳解决方法,可见一个算法的优劣是通过一定的准则来规定的。通过这学期的对《计算机算法分析设计》这门课程的学习让我们充分的了解到了计算机算法的多样性和复杂性,让我们更加细心和耐心的去对待这门课程。例如甲某要去某个地方旅游,他有很多种方案到旅游地,但是不见的每种方案都是合理最优的!这时就是需要考虑透过一定的算法来得到自己的最优路线。所以可见算法就是以最少的成本、最快的速度、最好的质量开发出合适各种各样应用需求的软件,必须遵循软件工程的原则,设计出高效率的程序。一个高效的程序不仅需要编程技巧,更需要合理的数据组织和清晰高效的算法。

引言
对于计算机科学来说,算法(Algorithm)的概念是至关重要的。算法是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。
算法可以理解为有基本运算及规定的运算顺序所构成的完整的解题步骤。或者看成按照要求设计好的有限的确切的计算序列,并且这样的步骤和序列可以解决一类问题。算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。
一个算法应该具有以下五个重要的特征:
有穷性:一个算法必须保证执行有限步之后结束;
确切性:算法的每一步骤必须有确切的定义;
输入:一个算法有0个或多个输入,以刻画运算对象的初始情况,所谓0个输入是指算法本身定除了初始条件;
输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;
可行性:算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
计算机科学家尼克劳斯-沃思曾著过一本著名的书《数据结构十算法= 程序》,可见算法在计算机科学界与计算机应用界的地位。

1.问题描述
给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包容量为C。在选择装入背包的物品时,对每种物品i只有两种选择:装入背包或不装入背包,即不能将物品i装入背包多次,也不能只装入物品i的一部分。问:如何选择装入背包的物品,使得装入背包中物品的总价值最大?
2.算法设计与分析
2.1算法分析
在0-1背包问题中,物体被装入一个背包,或者不被装入背包,设xi表示物品i装入背包的情况,则当xi=0时,表示物品i没有被装入背包,xi=1时,表示物品i被装入背包。假设有五个物品,其重量分别是{2,2,6,5,4},价值分别是{6,3,5,4,6},背包的容量为10。根据动态规划函数,用一个(n+1)×(C+1)的二维表V,V[i][j]表示把前i个物品装入容量为j的背包中获得的最大价值。

按下述方法来划分阶段:第一阶段,只装入前1个物品,确定在各种情况下的背包能够得到的最大价值;第二阶段,只装入前2个物品,确定在各种情况下的背包能够得到的最大价值;以此类推,直到第n个阶段。最后,V(n,C)便是在容量为C的背包中装入n个物品时取得的最大价值。
为了确定装入背包的具体物品,从V(n,C)的值向前推,如果V(n,C)>V(n-1,C),表明第n个物品被装入背包,前n-1个物品被装入容量为C-wn的背包中;否则,第n个物品没有被装入背包,前n-1个物品被装入容量为C的背包中。以此类推,直到确定第1个物品是否被装入背包中为止。
2.2算法设计
设n个物品的重量存储在数组w[n]中,价值存储在数组v[n]中,背包容量为C,数组V[n+1][C+1]存放迭代结果,其中V[i][j]表示前i个物品装入容量为j的背包中获得的最大价值,数组x[n]存储装入背包的物品,动态规划法求解0/1背包问题的算法如下:
int KnapSack(int n, int w[ ], int v[ ])
{
for (i=0; i<=n; i++) //初始化第0列
V[i][0]=0;
for (j=0; j<=C; j++) //初始化第0行
V[0][j]=0;
for (i=1; i<=n; i++) //计算第i行,进行第i次迭代
for (j=1; j<=C; j++)
if (j<w[i]) V[i][j]=V[i-1][j];
else V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]);
j=C; //求装入背包的物品
for (i=n; i>0; i–){
if (V[i][j]>V[i-1][j]) {
x[i]=1;
j=j-w[i];
}
else x[i]=0;
}
return V[n][C]; //返回背包取得的最大价值
}

3.程序编码与调试分析
3.1程序编码
#include<stdio.h>
#include<math.h>
int max(int x,int y){
if(x>=y)
return x;
else
return y;
}
int KnapSack(int n,int C,int *w,int *v,int V[][11]) {
int i,j,x[i];
for (i=0;i<=n;i++) //初始化第0列
V[i][0]=0;
for (j=0;j<=C;j++) //初始化第0行
V[0][j]=0;
for (i=1;i<=n;i++) //计算第i行,进行第i次迭代
for (j=1;j<=C;j++)
if (j<w[i])
V[i][j]=V[i-1][j];
else
V[i][j]=max(V[i-1][j], V[i-1][j-w[i]]+v[i]);
j=C; //求装入背包的物品
for (i=n; i>0; i–){
if (V[i][j]>V[i-1][j]) {
x[i]=1;
j=j-w[i];
}
else x[i]=0;
}
for(i=0;i<=n;i++)
{for(j=0;j<=C;j++)
printf("%3d “,V[i][j]);
printf(”\n");
}
printf(“背包取得的最大价值:”);
printf("%d",V[n][C]); //返回背包取得的最大价值
}
int main(){
int n=5,C=10,i;
int V[6][11];
int w[6],v[6];
for(i=1;i<6;i++)
scanf("%d",&w[i]);
for(i=1;i<6;i++)
scanf("%d",&v[i]);
KnapSack(5,10,w,v,V);
}

3.2调试分析
以上0-1背包问题的代码的时间复杂度为O(nc).(n表示物品的总数,c为重量限制背包容量),当背包容量c很大时,算法需要的计算时间比较多。动态规划依赖于上一个或者上一行的解,所以我常在输出子序列的时候出现问题,这源自于对动态规划的知识不是很了解。
4.测试结果

5.自学知识
在这个程序设计中,涉及了动态规划,动态规划是解决多阶段决策问题常用的最优化理论,其基本思想是沿着决策的阶段划分自问题,决策的阶段可以随时间划分,也可以随着问题的转换状态划分。
设计动态规划算法,通常可按照以下几个步骤进行:
(1)找出最优解的性质,并刻画其结构特征。
(2)递归地定义最优解的值。
(3)以自底而上的方式计算出最优值。
(4)根据计算最优值时得到的信息,构造一个最优解。

6.总结
计算机软件专业中,算法分析与设计是一门非常重要的课程,很多人为它如痴如醉。很多问题的解决,程序的编写都要依赖它,在软件还是面向过程的阶段,就有程序=算法+数据结构这个公式。算法的学习对于培养一个人的逻辑思维能力是有极大帮助的,它可以培养我们养成思考分析问题,解决问题的能力。
如果一个算法有缺陷,或不适合某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂性和时间复杂度来衡量。算法可以使用自然语言、伪代码、流程图等多种不同的方法来描述。计算机系统中的操作系统、语言编译系统、数据库管理系统以及各种各样的计算机应用系统中的软件,都必须使用具体的算法来实现。算法设计与分析是计算机科学与技术的一个核心问题。因此,学习算法无疑会增强自己的竞争力,提高自己的修为,为自己增彩。
学习算法分析与设计使我对软件基础知识中算法的地位有了充分的了解,认识到光书本的知识的确不行,还是要理论联系实践才行。因此不断的练习是必要的,上机实践更重要虽然课程结束了,但我依然还会继续学习算法分析与设计,以后我将充分利用所学到我实际的开发项目中。

7.参考文献
[1] 谭浩强等. 《C语言程序社会》,清华大学出版社,2013.
[2] 王晓华等. 《算法的乐趣》, 人民邮电出版社, 2015.

  • 8
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值