算法设计课程设计报告Word格式文档下载.docx
《算法设计课程设计报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法设计课程设计报告Word格式文档下载.docx(8页珍藏版)》请在冰豆网上搜索。
作为初学者,我们可以用f(n)的数量级O来粗略地判断算法的时间复杂性,如上例中的时间复杂性可粗略地表示为T(n)=O(n2)。
2.空间复杂性:
例2:
将一一维数组的数据(n个)逆序存放到原数组中,下面是实现该问题的两种算法:
算法1:
fori:
b[i]:
=a[n-i+1];
fori:
a[i]:
=b[i];
算法2:
=1tondiv2do
begin
t:
=a[i];
a[i]:
=a[n-i-1];
a[n-i-1]:
=t
end;
算法1的时间复杂度为2n,空间复杂度为2n
算法2的时间复杂度为3*n/2,空间复杂度为n+1
显然算法2比算法1优,这两种算法的空间复杂度可粗略地表示为S(n)=O(n)
3、从下面算法策略中自选一组,结合某具体问题的求解来介绍算法思想,并加以总结、比较:
递归与分治、动态规划与贪心法、回溯法与分支限界法
动态规划算法类似于分治法,基本思想也是将待求解问题分解成若干个子问题。
化整为零,减少了运算量。
贪心算法,是永不知足的求最优解,有点类似于我们所说的完美主义者。
两者之间有相同点,总结来说某种程度上,动规是贪心的泛化,贪心是动规的特例
贪心:
A最优+B最优
动态规划:
(A+B)最优
就单步而言
贪心的A最优是前一步的结果,B最优需要遍历找到
动态规划的A为前一步的可行解,需要选择一个B后再去找A
动态规划算法之0-1背包问题:
给定n种物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n。
这2类问题都具有最优子结构性质,极为相似,但背包问题可以用贪心算法求解,而0-1背包问题却不能用贪心算法求解。
用贪心算法解背包问题的基本步骤是,首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
若将这种物品全部装入背包后,背包的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。
依此策略一直地进行下去,直到背包装满为止。
具体代码如下:
1.//4d2
贪心算法
背包问题
2.#include
"
stdafx.h"
3.#include
<
iostream>
4.using
namespace
std;
5.
6.const
int
N
=
3;
7.
8.void
Knapsack(int
n,float
M,float
v[],float
w[],float
x[]);
9.
10.int
main()
11.{
12.
float
M
50;
//背包所能容纳的重量
13.
//这里给定的物品按单位价值减序排序
14.
w[]
{0,10,20,30};
//下标从1开始
15.
v[]
{0,60,100,120};
16.
17.
x[N+1];
18.
19.
cout<
背包所能容纳的重量为:
M<
endl;
20.
待装物品的重量和价值分别为:
21.
for(int
i=1;
i<
=N;
i++)
22.
{
23.
["
]:
("
w[i]<
"
v[i]<
)"
24.
}
25.
26.
Knapsack(N,M,v,w,x);
27.
28.
选择装下的物品比例如下:
29.
30.
31.
x[i]<
32.
33.
34.
return
0;
35.}
36.
37.void
x[])
38.{
39.
//Sort(n,v,w);
//这里假定w[],v[]已按要求排好序
40.
i;
41.
for
(i=1;
=n;
42.
43.
x[i]=0;
//初始化数组x[]
44.
45.
46.
c=M;
47.
i++)//物品整件被装下,x[i]=1
48.
49.
if
(w[i]>
c)
50.
51.
break;
52.
53.
x[i]=1;
54.
c-=w[i];
55.
56.
57.
//物品i只有部分被装下
58.
(i<
=n)
59.
60.
x[i]=c/w[i];
61.
62.}
程序运行结果为:
动态规划之01背包
状态转换方程
f[i,j]=Max{f[i-1,j-Wi]+Pi(j>
=Wi),
f[i-1,j]}
f[i,j]表示在前i件物品中选择若干件放在承重为j的背包中,可以取得的最大价值。
Pi表示第i件物品的价值。
决策:
为了背包中物品总价值最大化,第i件物品应该放入背包中吗?
题目描述:
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
name
weight
value
1
2
3
4
5
6
7
8
9
10
a
12
15
b
11
c
d
e
这表是至底向上,从左到右生成的。
为了叙述方便,用e2单元格表示e行2列的单元格,这个单元格的意义是用来表示只有物品e时,有个承重为2的背包,那么这个背包的最大价值是0,因为e物品的重量是4,背包装不了。
对于d2单元格,表示只有物品e,d时,承重为2的背包,所能装入的最大价值,仍然是0,因为物品e,d都不是这个背包能装的。
同理,c2=0,b2=3,a2=6。
对于承重为8的背包,a8=15,是怎么得出的呢?
根据01背包的状态转换方程,需要考察两个值,
一个是f[i-1,j],对于这个例子来说就是b8的值9,另一个是f[i-1,j-Wi]+Pi;
在这里,
f[i-1,j]表示我有一个承重为8的背包,当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]表示我有一个承重为6的背包(等于当前背包承重减去物品a的重量),当只有物品b,c,d,e四件可选时,这个背包能装入的最大价值
f[i-1,j-Wi]就是指单元格b6,值为9,Pi指的是a物品的价值,即6
由于f[i-1,j-Wi]+Pi=9+6=15大于f[i-1,j]=9,所以物品a应该放入承重为8的背包
以下是actionscript3的代码
1.public
function
get01PackageAnswer(bagItems:
Array,bagSize:
int):
Array
2.{
3.
var
bagMatrix:
Array=[];
4.
i:
int;
item:
PackageItem;
6.
for(i=0;
bagItems.length;
8.
bagMatrix[i]
[0];
10.
for(i=1;
=bagSize;
11.
for(var
j:
int=0;
j<
j++)
item
bagItems[j]
as
if(item.weight
>
i)
//i背包转不下item
if(j==0)
bagMatrix[j][i]
else
bagMatrix[j][i]=bagMatrix[j-1][i];
//将item装入背包后的价值总和
itemInBag:
item.value;
continue;
35.
37.
38.
itemInBag
bagMatrix[j-1][i-item.weight]+item.value;
(bagMatrix[j-1][i]
?
bagMatrix[j-1][i]
:
itemInBag)
//find
answer
answers:
curSize:
bagSize;
for(i=bagItems.length-1;
i>
=0;
i--)
bagItems[i]
if(curSize==0)
if(i==0
&
curSize
0)
answers.push(item.name);
if(bagMatrix[i][curSize]-bagMatrix[i-1][curSize-item.weight]==item.value)
62.
-=
item.weight;
63.
64.
65.
answers;
66.}
四结合实际,谈谈本课程学习的收获、体会、建议与意见等。
通过算法设计与分析的讲解,我回归了以前的知识点,以前在学习C语言和C++的时候对贪心算法,回溯法,有一些了解,在老师的更细心讲解下我对算法的重要性和策略有更好的理解,在面向对象的时候学会了一个公式编程=数据结构+算法。
算法是指令,就像带兵打仗的将军,是挥斥方遒的决定性策略。
策略的评估可以用时间复杂度和空间复杂度来计算。