研究生算法设计课程报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(5)
3)按 的值由大到小
(6)
通过以上三式可知,第三种量度标准最优。
下面证明使用第三种策略的贪心算法所得到的贪心解是一个最优解。证明的基本思想即把这贪心解与任一最优解相比较,若这两个解不同,就去找开始不同的第一个 ,然后设法用贪心解的这个 去代换最优解的那个 ,并证明最优解在分量代换前后的总效益无任何变化。反复进行这种代换,直到新产生的最优解与贪心解完全一样,从而证明了贪心解是最优解。
现以有序表(-15,-6,0,7,9,23,54,82,101)为例说明用二分检索算法查找Key=82的过程(这里假定表中各元素只含关键码)。首先,取整个有序表为检索区间,这通过分别置low、high为1、9来完成。因区间长度大于0,取区间中间位置mid = (1+9)/2 = 5,将mid位置上元素的关键码值9与Key=82比较。因9<82,将区间缩小为[6,9]。注意此新区间与原区间[1,9]的差别仅在于下界不同,修改区间的工作可通过修改下界low= mid+1=5+1完成。由于循环终止条件未满足,重复上述过程。这时区间中点为mid=(6+9)/2=7,比较结果82>54表明区间应改为[8,9],这一修改由下界的修改low = mid+1=7+1完成。再次进行比较时,区间中点为mid=(8+9)/2=8,比较结果表明F[mid]正是待查元素,检索成功,返回结果为mid=8。
print a[h],' '
由上面代码可以看出,有两层循环即时间复杂度为
在下面是我用Python实现的汉诺塔问题代码:
defhanoi(n,A,B,C):
if n == 1:
print 'move ',A,' to ',C
else:
hanoi(n-1,A,C,B)
print 'move ',A,' to ',C
具体的贪心策略求解部分背包问题Python代码为:
defgreedknap(n,M,p,w,pw,pww):
fori in range(n):
for j in range(i,n):
if pw[j] > pw[i]:
t = pw[i]
pw[i] = pw[j]
pw[j] = t
m = 0.0
sm = 0.0
print 'input the weight of ',n,' bags:'
fori in range(n):
t2 = raw_input()
t2 = float(t2)
w.append(t2)
dpw = {}
fori in range(n):
pww = "%.1f"%float(p[i]/w[i])
本章分别介绍了如何利用动态规划来求解多段图、每对结点间的最短路径、最优二分检索树、矩阵连乘、0|1背包问题、TSP问题以及调度问题。
下面我重点介绍一下用动态规划方法解决最优二分检索树以及0|1背包问题。
(一)最优二分检索树问题
二分检索树即T是一棵二元树,它或者为空,或者其每个结点含有一个可比较大小的数据元素,并且:
low = mid + 1
continue
elif x == A[mid]:
j = mid
break
return j
if __name__ == '__main__':
A = [-15,-6,0,7,9,23,54,82,101]
n = len(A)
while True:
x = raw_input("Find Number:")
二分检索法的效率可以通过二分检索的决策树进行衡量。其平均检索长度与最大检索长度相近,效率较高。但它要求被检索序列事先按关键码的次序(递增或递减)排列,而排序本身是一种很费时的运算;另外,二分检索只适用于顺序存储结构,而在顺序结构中插入和删除都比较困难。因此,二分检索特别适用于那种一经建立就很少改动、而又需要经常检索的线性表。
hanoi(n-1,B,A,C)
if __name__ == '__main__':
hanoi(2,'a','b','c')
由上面的代码可以看出,其有递推关系 ,即时间复杂度为 。
算法的时间复杂度分类有1)P算法,即多项式时间复杂度,如上面的冒泡排序算法;2)NP算法,即指数时间复杂度,如上面的汉诺塔问题算法。
pw.append(pww)
dpw[i] = pw[i]
greedknap(n,M,p,w,pw,pww)
通过对本章的学习,我了解到贪心算法在对问题求解时,总是做出在当前看来是最好的选择,也就是说,不从整体最优上加以考虑,他所做出的仅是某种意义上的局部最优解。贪心算法存在以下问题:1)不能保证求得的最后解是最佳的;2)只能用来求某些最大或最小解的问题;3)只能确定某些问题的可行性范围。
在进行算法时间复杂度分析前,我们先作三个约定即其为串行计算机、计算机均匀存储且存储器足够大、基本运算时间一样。
下面我们利用两个例子对算法时间复杂性进行分析,来引出算法时间复杂度分类。
在下面我用Python实现的冒泡排序代码:
n = raw_input("number:")
print n
n = int(n)
x = int(x)
i = binsrch(A,n,x)
printi
由上面的代码实现可以看出,其时间复杂度为 。
通过对本章的学习,我了解到分治法的优点是通过将原问题分解成较小的子问题,使用递归求解,程序简洁易懂,而且非常容易实现;同时,它的缺点是将原问题分解的过程比较难,方法不易想到,而且当子问题大量重复时,递归会很大的增加时间复杂度。

动态规划是为解决多阶段决策问题的“最优性原理”所创建的最优化的一种新的算法设计方法。
多阶段决策问题即该问题可以分为若干个阶段,且在第i+1阶段时的行为只依赖于第i阶段,而与i阶段之前的过程如何达到这种状态的方式无关。
最优性原理即无论过程的初始状态和初始决策是什么,其余的决策都必须相对于初始决策所产生的状态构成一个最优决策序列。
a = []
fori in range(n):
x = raw_input()来自百度文库
x = int(x)
a.append(x)
for j in range(n):
for k in range(j,n):
if a[j] > a[k]:
t = a[j]
a[j] = a[k]
a[k] = t
for h in range(n):
break
elif (M - m) >= w[k]:
m = m + w[k]
sm = sm + p[k]
print 'the max value is ',sm
if __name__ == '__main__':
while True:
n = raw_input("knaps num:")
n = int(n)
具体的Python代码实现为:
defbinsrch(A,n,x):
j = -1
low = 0
high = n - 1
while (low <= high):
mid = (low + high)/2
if x < A[mid]:
high = mid - 1
continue
elif x > A[mid]:
使上式取最小值即为最优二分检索树。
假定 为根,其左子树L包括 ,右子树R包括
左子树成本:
右子树成本:
成功检索与不成功检索的单个成本:
总成本

总成本:
将其一般化有
fori in range(n):
k = 0
forkey,val in dpw.items():
ifval == pw[i]:
k = key
break
else:
continue
while m < M:
if (M - m) < w[k]:
sm = sm + ((M - m)/w[k])*p[k]
m = M
中 国 地 质 大 学
研究生课程论文封面
课程名称算法设计与分析
教师姓名
研究生姓名
研究生学号
研究生专业
所在院系计算机学院
类别:B.硕士
日期:年 月 日
评 语
对课程论文的评语:
平时成绩:
课程论文成绩:
总 成 绩:
评阅人签名:
注:1、无评阅人签名成绩无效;
2、必须用钢笔或圆珠笔批阅,用铅笔阅卷无效;
3、如有平时成绩,必须在上面评分表中标出,并计算入总成绩。
第一章
算法即基于规则的信息变换或物理状态变换、符号串变换。其特点是1)确定性:即无二义性;2)能行性:其特点是具有数学模型、能用程序表示、可以在有限的时间内执行完;
3)有限性:即可以研究算法的复杂性;4)输入:可有可无,即把信息存在内存上;5)输出:一定存在,即将信息显示在外部设备上。
算法分析即对算法的时间复杂度与空间复杂度的分析。算法的具体执行时间是硬件、操作系统、语言、DOS的执行时间,但我们不分析其具体执行时间,而分析其时间复杂度即复杂性随问题规模变化的规律。
第二章
一般而言,计算机求解问题的规模越小,所需的计算时间也越少。对于规模为N的问题,分治策略将其分解为k个(k = 2, 3, 4,…,一般取k=2)相同类型的子问题,每个子问题的规模相对较小且相互独立;递归地求解这些子问题,并将所得结果合并而求出原来问题的解,这就是分治策略的基本思想。分治策略算法通常分为三个部分:分割、求解、合并。
证明步骤:

若x不是最优,
设k是使 的最小下标,一定存在 。
把 增加到 ,则必须从 中减去相同的量,使得所有容量仍为M,则导致新解 。若 ,则y不可能是最优解,若已知这两个和数相等,同时z=x,则x就是最优解,若 ,则需要重复上面的讨论,或者证明y不是最优解,或者把y转换成x,从而证明了x也是最优解,证毕。
1)T的左子树的所有元素比根结点T的元素小;
2)右子树的所有元素比根结点T的元素大;
3)T的左子树和右子树也是二分检索树;
且树中所有结点中的元素是互异的。
假定所给出的标识符集是 。
设 是对 检索的概率, 是正被检索的标识符x的概率,而x满足 。
为不成功检索的概率且 。
构造一棵对于 最优的二分检索树,预期成本公式如下:
极大化 (1)
约束条件 (2)
(3)
其中,式(1)为目标函数,式(2)和(3)是约束条件。满足约束条件的任一集合 是一个可行解(即能装下),使目标函数取最大值的可行解是最优解。
以n=3,M=20, 。
用贪心策略来求解部分背包问题,首先应选出最优量度标准:
1)按p的值由大到小:
(4)
2)按w的值由小到大:
由分治法所得到的子问题与原问题有相同的类型。
分治法中一个比较有代表性的例子是二分检索,二分检索即对所求解的问题(或子问题)所选下标k都是其元素中间元素(k = L( ))的下标,其所产生的算法为二分检索。二分检索是针对有序表的检索。所谓有序表,是指线性表中的所有数据元素按关键码值的某种次序进行递增或递降的排列,二分检索法的基本思想是:每次将待查区间中间位置上的数据元素的关键码值与给定值Key比较,若不等则缩小检索区间并在新的区间内重复上述过程,直到检索成功或检索区间长度为0(检索不成功)为止。
M = raw_input("knaps volumn:")
M = float(M)
p = []
w = []
pw = []
print 'input the value of ',n,' bags:'
fori in range(n):
t1 = raw_input()
t1 = float(t1)
p.append(t1)
计算问题分为三大类为:
1、由难到易的校正技术(迭代技术)
例如将多项式 进行泰勒展开;
2、由粗到精的松弛技术
其中又分为直接法和迭代法;
3、由大到小的分治技术
例如并行算法。
通过对本章的学习,我了解到学习算法所应涉及的内容,以及对算法进行分析时所关注的最重要的两个内容:即时间复杂度和空间复杂度。通过对特定的问题进行分析,我们可以对时间复杂度大的问题进行牺牲空间资源来降低时间复杂度;反之,我们可以对空间复杂度大的问题进行牺牲时间资源来降低空间复杂度。

贪心算法即求解优化问题的方法。优化问题即给定n个输入,结果为其某个子集组成且必须满足约束条件;其中1)满足约束条件的子集称为该问题的可行解,2)定义一个可行解优劣的函数为目标函数,3)此目标函数取得最优值的结果为最优解。选择能产生问题最优解的最优量度标准是贪心算法设计求解的核心问题。
贪心算法中比较典型的例子是部分背包问题,部分背包问题即已知n种物品和一个可容纳M重量的背包,每种物品i的一部分 放入背包就会得到 的效益,这里, 。采用怎样的背包问题才会使装入背包物品的总效益最大?有上述叙述,可将这个问题形式描述如下:
相关文档
最新文档