三 、例子 :
例 6 设集合 S 有 n 个元素 , 求 S 的最大和最小元素。为简单起见 , 设 n = 2m , m>=0 。
求集合 S 的最大元素 , 可以采用下述算法。
-----------------------------------------------------------------------------------------------------
Procedure MAX(S)
begin
MAX ß S 中的任一元素
for S 中的所有其它元素 x do
It X > MAX then MAX ß x
end
-----------------------------------------------------------------------------------------------------
结论 : 利用此算法 , 进行 n - 1 次比较后就可以求出 S 的最大元素。用 n - 2 次比较就可以求出剩下的 n - 1 个元素的最小元素。所以如果要找出 S 中的最大和最小元素 , 总共要进行 ( n – 1 ) + ( n – 2 ) = 2n - 3 次比较。
* 如果我们使用分治法来改善此算法 , 则可以减少比较的次数。
(a) 把 S 分成大小相等的两个子集 S1 和 S2 , 所以 S1 与 S2 各有 n / 2 = 2m-1 个元素。
(b) 对 S1 和 S2 分别反复使用分治法 , 求出最大及最小元素。
(c) 比较 S1 和 S2 所求出的最大及最小元素 , 就可以得到 S 的最大及最小元素。
-----------------------------------------------------------------------------------------------------
produce MAXMIN(S)
begin
1. if ||S|| = 2 then
begin
2. let S = {a, b}
3. return (MAX(a, b), MIN(a, b))
end
else
begin
4. 分 S 成两个子集 S1 和 S2 , 且 ||S1 || = ||S2 || = 1/2||S||
5. (max1, min1) ß MAXMIN(S1 )
6. (max2, min2) ß MAXMIN(S2 )
7. return (MAX(max1, max2), MIN(min1, min2))
end
end
-----------------------------------------------------------------------------------------------------
结论 : 如果 S 只有两个元素 , 那就在第 3 行进行一次比较 , 如果 S 有两个以上的元素 , 则至第四行将 S 分成两个子集 , 并在 5, 6 行递归使用 MAXMIN, 第 7 行比较 max1, max2 及 min1, min2 。设 S 有 n 个元素 , 则 n = 2 时 , T(2) = 1, n > 2 时 , T(n) = 3/2n - 2 , 就是说明了在 n 个元素的集合中寻找最大及最小元素至少要进行 (3/2n – 2) 次 , 所以使用分治法可以减少比较的次数 , 优于上一个算法。
|
T(n) = aT(n/c) + bn n > 1
|
O(n) a < c
|
O(n ) a > c
第一小节 动态规划问题
例 1 :在 x +x2 +x3 +…+xn =a 是约束条件下, 求 的极大值 .
令 ( 0 )
令 且
可得 a - x=x, 所以 x=a/2
故
同理
令
所以 a - x=2x , x=a/3
所以 f3 (a)=
用数学归纳法可以证明: fn (a) = , x1 =x2 =x3 =…=xn =
证明: 1 : n=1 …
2 :设 fn (a) = , x1 =x2 =x3 =…=xn = 成立,则
fn+1 (a)=max( +fn (a-x))=max( )
令 y=
y’= =
所以 nx=a-x ,(n+1)x=a
x=
fn+1 (a)= +n =
我们刚才的解题策略是:“摸着石头过河”, f2 利用 f1 的结果, f3 又利用 f2 的结果。。。。。。类似于游戏中的一个勇士打败了一些敌人后得到一件武器,然后去打败另一个强大一些的对手,得到一件更好的武器,接着打败更强大的敌人。。。。。最后取得胜利。。。
在实际生活中,有这么一类问题,它们的活动过程可分为若干个阶段,而且在任一阶段 后的行为仅依赖于第 I 阶段的过程状态,而与 I 阶段之前的过程如何达到这种过程如何达到这种状态的方式无关,这样的过程就构成了一个多阶段决策过程。在 50 年代,贝尔曼( Richard Bellman )等人根据这类问题的多阶段决策的特性,提出了解决问题的“最优性原理”从而创建了最优化问题的一种最新的算法设计方法——动态规划。
回溯法
探索法最经典的例子就是 “装箱问题” 了。
问题:有容积为 T 0 的箱子 B i 个,另有大小为 t i 的目标, i = ,要求把所有的目标放入数目尽可能少的箱子里去,目标不能分割,每个箱子装的目标体积之和不能超过 T 0 。
这里给出解此类问题的 4 种算法:
1) FF 算法:( First Fit 首次适合)
L 是给定的目标序列,把 L 中的第一个放入 B 1 ,然后拿第二个,看是否还能放入 B 1 ,能则放入,不能则放入 B 2 ,依次。就是说尽量放入下标最小的 B i 。
2) FFD 算法:
如果把 L 以降序排列,那么 FF 算法就编程了 FFD 算法。
3) BF 算法:
L 顺序任意,装箱的方法与 FF 算法相似,但是放下一个目标时找的是能尽量造成最小空间的那个箱子。
4) BFD 算法:
把 L 以降序排列的 BF 算法。
这里以 FFD 算法为例。
根据书上,有这么一个误差公式:
其中 N FFD 是用 FFD 算法求得的近似解, N 0 是最佳解, 是任意大于 0 的数。就是说 FFD 算法产生的结构大概要比完美的情况多出那么个 23% 。
例子: 设 是任意选定的小正实数,所有箱子的尺寸为 1 。
有尺寸为 的目标 6 个,尺寸为 的目标 6 个,尺寸为 的目标 12 个,尺寸为 的目标 6 个。
那么看最佳解法的箱子是 9 个:
回溯法