第五讲:易解问题与难解问题
/* 测试用主函数 */ main() { hanoi(N, 'A', 'B', 'C'); }
21
当n=64时,移动次数=?花费时间=?
h(n)=2h(n-1)+1
= 2(2h(n-2)+1)+1=22h(n-2)+2+1 = 23h(n-3)+22+2+1
……
=2nh(0)+2n-1+…+22+2+1 = 2n-1+…+22+2+1=2n-1
一种选择排序算法是:从n个数中挑出最小的数,再
从n-1个数中挑出第二小的数….. 时间复杂性与n有关,大概是n+(n-1)+…+1=1/2(n(n+1)), 忽略常数项,取最大的指数,记为O(n2)。 最快的算法是快速排序算法,时间复杂度为O(nlogn)。
2.2 梵天塔问题
相传印度教的天神梵天在创造地球这一世界时,建了
15
递归的例子
计算n! 根据公式
当n=0 =n*(n-1)! 当n!=0 函数参数为n int f(int n) { if (!n) return 1; else return (n*f(n-1)); }
n!=1
16
递归的例子
斐波那契数列(fibonacci) f(0)=0
例如:n!=f(n),为了计算f(n),将它推到比原问题更简单的问题f(n-1),
即f(n)=f(n-1)*n,而计算f(n-1)比计算f(n)简单,因为f(n-1)比f(n)更加接 近已知解0!=1 使用递推要注意 (1)递推应有终止之时,例如当n=0时,0!=1为递推终止条件,所谓终止 条件就是指在此条件下问题的解时明确的,缺少终止条件会使算法失 败。 (2)简单问题表示离递推终止条件更接近的问题。简单的问题与原 问题其解的算法是一致的,其差别主要反映在参数上,例如,f(n-1)比计 算f(n)更简单,因为f(n-1)比f(n)参数少1。参数变化使问题递推到有明 确解。
C
A
B
( 3 ) A TO B
C
19
穷举演算(续)
A B C A B
( 6 ) B TO A
C
( 5 ) A TO C
A
B
(8 ) A TO C
C
A
B
(7 ) B TO C
C
20
梵塔问题:子程序
/* 程序HANOI.C: 梵塔问题-*/ #include <stdio.h> #define N 3 void move(int from, int to) { printf("From %c to %c\n", from, to); } void hanoi(int n, int p1, int p2, int p3) { if(n==1) move(p1, p3); else { hanoi(n-1, p1, p3, p2); move(p1, p3); hanoi(n-1, p2, p1, p3); } }
阿达尔定律
设f为求解某个问题的计算存在的必须串行执行的操作
占整个计算的百分比,p为处理器的数目,Sp为并行计 算机系统最大的加速能力,则
C
A
B
D
欧拉回路
欧拉给出了哥尼斯堡七桥问题 的证明,还用数学方 法给出了三条判定规则(判定每座桥恰好走过一次,不
一定回到原点, 即对欧拉路径的判定): 如果通奇数座桥的地方不止两个,满足要求的路线 是找不到的。 如果只有两个地方通奇数座桥,可以从这两个地方 之一出发,找到所要求的路线。 如果没有一个地方是通奇数座桥的,则无论从哪里 出发,所要求的路线都能实现。 根据第3点,可以得出,任一连通图存在欧拉回路的 充分必要条件是所有顶点均有偶数度.
2.1 排序问题
随机给出n个数,要求对它们进行排序。比如:
8,2,7,6,4,12 对于排序问题,有多种算法。 一种选择排序算法是:从n个数中挑出最小的数,再 从n-1个数中挑出第二小的数….. 那么,在这些众多的算法中,如何来比较谁的速度更 快? 事后分析:机器的运行时间? 事前分析:与问题规模有关的表达式,表示算法中基 本操作的执行次数。
在计算复杂性理论中,将所有可以在多项式时间内 求解的问题称为P类问题,而将所有在多项式时间内 可以验证的问题称为NP类问题。由于P类问题采用的 是确定性算法,NP类问题采用的是非确定性算法,而 确定性算法是非确定性算法的一种特例,因此,可以 断定PNP。
2.4 证比求易算法
为了更好地理解计算复杂性的有关概念,我国学者 洪加威曾经讲了一个被人称为“证比求易算法”的童 话,用来帮助读者理解计算复杂性的有关概念,大致 内容如下。 从前,有一个酷爱数学的年轻国王艾述向邻国一位 聪明美丽的公主秋碧贞楠求婚。公主出了这样一道题: 求出48 770 428 433 377 171的一个真因子。若国王能在 一天之内求出答案,公主便接受他的求婚。
需要移动盘子的次数为:
264-1=18446744073709551615
假定每秒移动一次,一年有31536000秒,则僧侣们一
刻不停地来回搬动,也需要花费大约5849亿年的时间。 假定计算机以每秒1000万个盘子的速度进行搬迁,则 需要花费大约58490年的时间。 这样的问题也称为难解问题,虽然理论上可以解决, 但是在n值比较大的情况下,计算时间太大。对于此类 问题,人类也一直在寻找是否有更快的计算算法。
2.3 算法复杂性中的难解性问题、P类问题 和NP类问题
算法复杂性包括算法的空间以及时间两方面的复杂性 问题,梵天塔问题主要讲的是算法的时间复杂性。
关于梵天塔问题算法的时间复杂度,可以用一个 指数函数O(2n)来表示,显然,当n很大(如10000) 时,计算机是无法处理的。相反,当算法的时间 复杂度的表示函数是一个多项式,如O(n2)时,则 可以处理。因此,一个问题求解算法的时间复杂 度大于多项式(如指数函数)时,算法的执行时 间将随n的增加而急剧增长,以致即使是中等规模 的问题也不能求解出来,于是在计算复杂性中, 将这一类问题称为难解性问题。人工智能领域中 的状态图搜索问题(解空间的表示或状态空间搜 索问题)就是一类典型的难解性问题。
顺序算法和并行算法
国王最先使用的是一种顺序算法,其复杂性表现在时
间方面, 后面由宰相提出的是一种并行算法,其复杂性表现在 空间方面。 直觉上,我们认为顺序算法解决不了的问题完全可以 用并行算法来解决,甚至会想,并行计算机系统求解 问题的速度将随着处理器数目的不断增加而不断提高, 从而解决难解性问题,其实这是一种误解。 当将一个问题分解到多个处理器上解决时,由于算 法中不可避免地存在必须串行执行的操作,从而大 大地限制了并行计算机系统的加速能力。
哈密尔顿回路问题
问题:在某个图G中,能不能找到这样的路径,即从一
点出发不重复地走过所有的结点,最后又回到原出发 点。
“哈密尔顿回路一次,而
“欧拉回路问题”是访问每条边一次。 对图G是否存在“欧拉回路”前面已给出充分必要 条件,而对图G是否存在“哈密尔顿回路”至今仍 未找到满足该问题的充分必要条件。
14
递归算法
回归
指当简单问题得到解后,回归到原问题的解上来。例如,
当计算完(n-1)!后,回归计算n*(n-1)!,即得到n!的值。 使用回归要注意 (1)当回归到原问题的解时,算法中所涉及的处理对象 是关于当前问题的,即递归算法所涉及的参数与局部处 理对象是有层次的。当解一问题的时候,有它的一套参 数与局部处理对象。当递推进入一个"简单问题"的时候。 这套参数与局部对象便隐藏起来,在解简单问题的时候 又有它自己的一套。当回归时,原问题的一套参数与局 部处理对象又活跃起来了。 (2)回归到原问题已经得到问题的解,回归并不引起其 他动作。
将n个盘由A移到C上的操作步骤为:
(1)将A上的n-1个盘借助C移到B上 (2)把A上剩下的一个盘由A移到C上 (3)将B上的n-1个盘借助A移到C上 这样处理后,问题的规模减少1。当n=1的 时候,就可以直接处理了。
18
穷举演算
n=3
A
B
(1)
C
A
B
C
( 2 ) A TO C
A
B
(4) C TO B
每次只能移动一个盘子; 盘子只能在三根柱子上来回移动,不能放在他
处; 在移动过程中,三根柱子上的盘子必须始终保 持大盘在下,小盘在上。
递归算法(重点掌握)
递归是一种特别有用的工具,不仅在数学中广泛应用,在
日常生活中也常常遇到。 以下使用递归算法来解决梵塔问题。
12
递归算法 在数学中几个熟知的数学定义:
国王立即回国,并向时任宰相的大数学家孔唤石求 教,大数学家在仔细地思考后认为这个数为17位,则 最小的一个真因子不会超过9位,
他给国王出了一个主意:按自然数的顺序给全国的老百
姓每人编一个号发下去,等公主给出数目后,立即将它 们通报全国,让每个老百姓用自己的编号去除这个数, 除尽了立即上报,赏金万两。
通过这7座桥到各城区游玩,问题:寻找走遍这7座
桥的路径,要求过每座桥只许走一次,最后又回到 原出发点。
北 区
岛 区
东 区
南 区
问题的抽象
1736年,大数学家列昂纳 德· 欧拉(L.Euler)发表了关
于“哥尼斯堡七桥问题”的 论文。 他抽象出问题最本质的东 西,忽视问题非本质的东 西(如桥的长度等),从 而将哥尼斯堡七桥问题抽 象为一个数学问题,即经 过图中每边一次且仅一次 的回路问题了。