< align=center><b> 贪婪算法</b></P> 虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。一般情况下,为了获得较好的性能,必须对算法进行细致的调整。但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。- E' c v$ |& X1 z6 j* `4 S
8 I% g( a1 i/ ]+ S( G8 z2 q2 L# N }. n 本章首先引入最优化的概念,然后介绍一种直观的问题求解方法:贪婪算法。最后,应用该算法给出货箱装船问题、背包问题、拓扑排序问题、二分覆盖问题、最短路径问题、最小代价生成树等问题的求解方案。; P7 U7 I) y- h& y
5 G w( Y' _3 Z1 i' B: }
( z# Y; t. n# \% {0 B
. T8 Q% t6 P0 F- K$ L, {
< align=center><EM> 最优化问题</EM></P> % T7 ]5 O% F s4 F( ?<>本章及后续章节中的许多例子都是最优化问题( optimization problem),每个最优化问题都包含一组限制条件( c o n s t r a i n t)和一个优化函数( optimization function),符合限制条件的问题求解方案称为可行解( feasible solution),使优化函数取得最佳值的可行解称为最优解(optimal solution)。 ; B0 p6 l3 w% e$ Q* ?# ~7 t 3 k! U8 F9 N* a. h8 }, |8 ]( C 例1-1 [ 渴婴问题] 有一个非常渴的、聪明的小婴儿,她可能得到的东西包括一杯水、一桶牛奶、多罐不同种类的果汁、许多不同的装在瓶子或罐子中的苏打水,即婴儿可得到n 种不同的饮料。根据以前关于这n 种饮料的不同体验,此婴儿知道这其中某些饮料更合自己的胃口,因此,婴儿采取如下方法为每一种饮料赋予一个满意度值:饮用1盎司第i 种饮料,对它作出相对评价,将一个数值si 作为满意度赋予第i 种饮料。, \/ T# f. F2 L& H2 V
! M: j* ?0 Y8 ^( k 通常,这个婴儿都会尽量饮用具有最大满意度值的饮料来最大限度地满足她解渴的需要,但是不幸的是:具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。设ai是第i 种饮料的总量(以盎司为单位),而此婴儿需要t 盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?. D% ]- J; h8 c3 O
3 G1 b3 {5 B' |& Q, h8 a7 e3 V) f4 A% A
设各种饮料的满意度已知。令xi 为婴儿将要饮用的第i 种饮料的量,则需要解决的问题是: . h0 e! x' t# G8 F8 }5 d# [ % n: z" m* g2 m+ R 找到一组实数xi(1≤i≤n),使n ?i = 1si xi 最大,并满足:n ?i=1xi =t 及0≤xi≤ai 。 6 o. `7 O' l& Q; j4 F: r* t7 J, k C4 i/ M2 X5 g2 p; D
需要指出的是:如果n ?i = 1ai < t,则不可能找到问题的求解方案,因为即使喝光所有的饮料也不能使婴儿解渴。 ; j- E. D0 l- _* B% x5 C, z& r) o* I. v. \
对上述问题精确的数学描述明确地指出了程序必须完成的工作,根据这些数学公式,可以对输入/ 输出作如下形式的描述: 2 ^/ V; u, o# d" f, [0 C5 N. J2 m1 g( l: @4 x$ s. C
输入:n,t,si ,ai(其中1≤i≤n,n 为整数,t、si 、ai 为正实数)。 5 D2 ?. [ Z+ w# |& D1 K* J/ z, d
输出:实数xi(1≤i≤n),使n ?i= 1si xi 最大且n ?i=1xi =t(0≤xi≤ai)。如果n ?i = 1ai <T,则输出适当的错误信息。 O: {5 {" A. T8 x! x7 B ; V; w( P, m. C 在这个问题中,限制条件是n ?i= 1xi =t 且0≤xi≤ai,1≤i≤n。而优化函数是n ?i= 1si xi 。任何满足限制条件的一组实数xi 都是可行解,而使n ?i= 1si xi 最大的可行解是最优解。 A& t) ~5 W' o* F