计算机算法分析与设计论文.docx
《计算机算法分析与设计论文.docx》由会员分享,可在线阅读,更多相关《计算机算法分析与设计论文.docx(8页珍藏版)》请在冰豆网上搜索。
![计算机算法分析与设计论文.docx](https://file1.bdocx.com/fileroot1/2022-12/13/ceed98f4-ef3a-4e8d-b42e-2cebb7baeb4c/ceed98f4-ef3a-4e8d-b42e-2cebb7baeb4c1.gif)
计算机算法分析与设计论文
计算机学院
算法设计与分析课程考查论文
题目0-1背包问题的算法设计策略对比与分析
专业
班级
学号
姓名
任课教师
完成日期
0-1背包问题的算法设计策略对比与分析
引言
算法,是在有限步骤内求解某一问题所使用的一组定义明确的规则。
通俗点说,就是计算机解题的过程。
在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法。
前者是推理实现的算法,后者是操作实现的算法。
对于程序员来说,算法的概念是至关重要的。
因为它是程序的灵魂,是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。
懂得了算法,就相当于领悟到了程序的灵魂,这样写起程序也会感到是一种惬意。
但不同的算法可能用不同的时间、空间或效率来完成同样的任务。
所以算法也有优劣,也有高效与低效之分。
一个算法应该具有以下五个重要的特征:
有穷性、确切性、输入、输出、可行性。
但我认为这些都是算法应该具备的最基本的特征,如果没了这些,我们又为什么花费心思学习它呢,所以这些并不是让我们热衷算法的资本。
高效,才是所有程序员所向往的,而算法又恰恰能满足人们对高效的要求,也正因为此,我才会在这写有关贪心算法的心得。
所谓贪心算法指的是为了解决在不回溯的前提之下,找出整体最优秀或者接近最优解的这样一种类型的问题而设计出来的算法。
贪心算法的基本思想是找出整体当中每个小小局部的最优解,并且将所有的这些局部最优解合起来形成整体上的一个最优解。
有人说贪心算法在解决问题的策略上目光短浅,只根据当前已有的信息就做出选择,而且一旦做出了选择,不管将来有什么结果,这个选择都不会改变。
换言之,也就是说贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优。
但我认为这种局部最优选择虽然并不总能获得整体最优解(OptimalSolution),但通常能获得近似最优解(Near-OptimalSolution),所以还是一种高效的选择。
接下来就让我们用实例来感受贪心算法的高效和思想。
贪心算法的基本思路和实现过程
基本思路:
1建立数学模型来描述问题。
2.把求解的问题分成若干个子问题
3.对每一子问题求解,得到子问题的局部最优解。
4.把子问题的解局部最优解合成原来解问题的一个解
实现该算法的过程:
a.从问题的某一初始解出发;
b.while能朝给定总目标前进一步do
c.求出可行解的一个解元素;
d.由所有解元素组合成问题的一个可行解。
贪心实例大演练
1.用贪心法求解付款问题。
假设有面值为5元、2元、1元、5角、2角、1角的货币,需要找给顾客4元6角现金,为使付出的货币的数量最少,首先选出1张面值不超过4元6角的最大面值的货币,即2元,再选出1张面值不超过2元6角的最大面值的货币,即2元,再选出1张面值不超过6角的最大面值的货币,即5角,再选出1张面值不超过1角的最大面值的货币,即1角,总共付出4张货币
在付款问题每一步的贪心选择中,在不超过应付款金额的条件下,只选择面值最大的货币,而不去考虑在后面看来这种选择是否合理,而且它还不会改变决定:
一旦选出了一张货币,就永远选定。
付款问题的贪心选择策略是尽可能使付出的货币最快地满足支付要求,其目的是使付出的货币张数最慢地增加,这正体现了贪心法的设计思想。
2.活动安排问题
这个问题指的是一个资源在某个时间点上只能由某个对象独占使用,因此出现了资源争夺的问题。
贪心算法在这里主要是解决资源的分配使用问题。
贪心算法给出了在一定的时间段上资源给最多个对象使用的一种最优解。
假设有活动集合E={n1,n2,n3...},并且每个活动的开始时间集合定义为S={s1,s2,s3...}结束时间集合定义为F={f1,f2,f3...},那么活动i和活动j的进行时间可以用区间[si,fi),[sj,fj)来表示,当si>=fj或者sj>=fi时我们称为两个活动不冲突,也就是说这两个活动可以被安排分别独占使用资源。
贪心算法来解决这个问题的思想是首先根据活动的结束时间将所有活动按升序排序,然后首先设定第一个活动选入可以独占使用资源的活动集合,之后依次比较待选集合当中活动是否与选中集合当中最后一个活动冲突,如果不冲突则选入活动。
整个思想确保了资源的在使用时间最长,并且将得出最多活动使用资源解集当中的一个解。
具体算法如下:
voidarrange(ints[],intf[],boolA[],intn)
{
A[0]=true;
intlastSelected=0;
for(inti=1;i if(s[i]>=f[lastSelected])
{
A[i]=true;
lastSelected=i;
}
else
A[i]=false;
}
这里也有特别需要注意的是地方,我们使用这个算法之前必须将所有的活动按照结束时间做升序排列,否则可能得到最差解。
3.贪心算法解背包
一个旅行者有一个最多能装C公斤重量的背包,已知n个重量和价值分别为ci>0和pi>0(i=1,2,…,n)的物品,选择哪些物品装入背包,可使在背包的容量限制之内所装物品的价值最大,这就是背包问题。
0-1背包特点是:
每种物品都仅有一件,可以选择放入或不放。
0-1背包问题:
给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
在选择装入背包的物品时,对每种物品i只有两种选择,即装入背包为1或不装入背包为0。
不能将物品i装入背包多次,也不能只装入部分的物品i。
021背包问题的主要特点是在选择物品i装入背包时,每种物品仅有一件,可以选择放或不放。
在求解0-1背包问题时,对贪心算法可以使用一些策略,使其得到的解更接近最优解。
具体方案如下:
(1)价值优先策略:
从剩余的物品中,选取价值最大的可以装入背包的物品。
此时,价值最大的优先被装入背包,然后装入下一个价值最大的物品,直到不能再装入剩下的物品为止。
(2)重量优先策略:
从剩余的物品中选取重量最小的物品装入背包中,这种策略一般不能得到最优解。
(3)单位价值优先策略:
根据价值/重量的比值,按照每一次选取剩下的物品中比值最大的物品装入背包,直到不能再装入为止。
以上三种策略都不能保证得到最优解,但三种策略相比较而言,第三种策略与最优解相差较小。
如果可以选择物品的一部分,用单位价值策略可以保证得到最优解。
在贪心算法时间复杂度的估算中,由于需要对重量或价值或两者的比值进行排序,所以贪心算法的时间复杂度为O(n*logn)。
下面是一种实现过程:
voidbagloading(intx[],floatp[],floatw[],floatc,intn)
{
//x[]取值为0或1,x[i]=1当且仅当背包i背装载;
//p[]是物品价值;
//w[]是物品重量;
//c表示背包的容量;
//n表示物品的件数;
floatt,k,pw[num];
inti,j,m,kk;
for(i=0;ipw[i]=p[i]/w[i];
//对各个点的坐标按由大到小进行排序(使用改进的冒泡排序)
m=n-1;
while(m>0)
{
kk=0;
for(j=0;jif(pw[j]{
t=p[j];
p[j]=p[j+1];
p[j+1]=t;
k=w[j];
w[j]=w[j+1];
w[j+1]=k;
kk=j;
}
m=kk;
}
//按p/w次序从大到小选择物品
i=0;
while(i{
x[i]=1;
c-=w[i];
i++;
}
}
intmain()
{
intn,all;
floatc,p1,w1;
floatp[num];
floatw[num];
intx[num];
inti;
cout<<"请输入物品的件数:
";
cin>>n;
cout<<"请输入背包的最大容量:
";
cin>>c;
cout<<"请依次输入各物品的价值与重量\n每个物品的价值与重量之间用空格隔开,回车后输入另一个物品:
"<//通过键盘依次输入各物品的价值与重量
for(i=0;i{
cin>>p[i]>>w[i];
}
//调用函数
bagloading(x,p,w,c,n);
//统计物品的总价值、总重量以及件数并输出
//统计装入物品的价值及重量并输出
all=0;
p1=0.0;
w1=0.0;
for(i=0;iif(x[i]==1)
{
all++;
p1=p1+p[i];
w1=w1+w[i];
}
cout<cout<<"所装物品总的价值为:
"<cout<<"所装物品总的重量为:
"<if(all>0)
{
cout<<"该背包共装入的这"<"<for(i=0;iif(x[i]==1)
cout<
}
system("pause");
return0;
}
分析:
约束条件是装入的物品总重量不超过背包容量:
∑wi<=M(M=150)
(1)根据贪心的策略,每次挑选价值最大的物品装入背包,得到的结果是否最优
(2)每次挑选所占重量最小的物品装入是否能得到最优解
(3)每次选取单位重量价值最大的物品,成为解本题的策略。
值得注意的是,贪心算法并不是完全不可以使用,贪心策略一旦经过证明成立后,它就是一种高效的算法,贪心算法还是很常见的算法之一,这是由于它简单易行,构造贪心策略不是很困难,可惜的是,它需要证明后才能真正运用到题目的算法中。
一般来说,贪心算法的证明围绕着:
整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的。
解释如下:
(1)贪心策略:
选取价值最大者。
反例:
W=30
物品:
ABC
重量:
281212
价值:
302020
根据策略,首先选取物品A,接下来就无法再选取了,可是,选取B、C则更好。
(2)贪心策略:
选取重量最小。
它的反例与第一种策略的反例差不多。
(3)贪心策略:
选取单位重量价值最大的物品。
反例:
W=30
物品:
ABC
重量:
282010
价值:
282010
根据策略,三种物品单位重量价值一样,程序无法依据现有策略作出判断,如果选择A,则答案错误。
对于选取单位重量价值最大的物品这个策略,可以再加一条优化的规则:
对于单位重量价值一样的,则优先选择重量小的!
这样,上面的反例就解决了。
当然,本题是个DP问题,用贪心法并不一定可以求得最优解,但毕竟用贪心算法是一种高效的算法。
其实动态规划算法是解决这个问题最好的方法,但并不是最快的。
4总结
通过以上三个实例,我们可以感受到贪心算法的好处简单的总结一下贪心算法的
在写论文的过程中,我上网查询了很多资料,并且也参考了书本里的内容,通过这些我对算法分析设计又有了进一步的了解,对算法的复杂度也有了新的认识。
对于我们常用的动态规划算法、回溯法、分支限界法、贪心算法等的思想有了进一步的了解,我相信这对我以后的学习是非常有用的。
虽然这门课程已经结束了,但是我所掌握的却很少,因此在接下来的时间里我还会继续学习算法分析与设计,从而能够运用这些算法解决更多的问题。
参考文献:
[1]王晓东.计算机算法设计与分析(第3版)电子工业出版社,2009.
[2]应莉0-1背包问题及其算法计算机与现代化(2009)06-0024-03
[3]徐颖回溯法在0-1背包问题中的应用软件导刊(2008)12-0054-02