IT民工
加油!

转自小驰的博客。去年认识的小驰,当时水平还差不多,现在我被远远甩在了后面,悲哀!

http://www.cnblogs.com/njuzyc/

两道好玩的问题及我对“贪心思想”看法

贪心是一种思想,所以我感觉给它下严格的定义不太合理。//要细致地研究它严格的定//义当然是必不可少的

在最优化问题中,贪心思想指每次决策都选择当前最优解,而不用考虑全局的情况。

贪心法是一种很高效的算法,但是容易知道贪心算法不一定正确,即从局部最优解不一定能够构造出全局最优解。

所以说,贪心的难点之一便是  贪心  正确性的证明。

总结出什么样的问题是能够用贪心法解决  是一件很困难的事情,不过大神们也弄出了一套名为“矩阵胚”的理论,矩阵胚用于贪心正确性的证明,但是貌似这套理论并没有涵盖所有的贪心问题(当然涵盖了相当大一部分),且太过于抽象(我看一点简单的部分都很吃力)。

 

 

下面是一个很好玩的问题:

例1:潜水比赛

     在马其顿王国的Ohide湖里举行了一次潜水比赛,其中一个项目是高山上跳下水,再潜水到达终点。这是一个团队项目,一支队伍由N个人组成。在潜水时必须 使用氧气瓶,但是每支队伍只有一个氧气瓶。最多两人同时使用一个氧气,但此时两人必须同步游泳,因此两人到达终点的时间等于较慢的一个人单独游到终点所需 要的时间。好在大家都很友好,因此任何两个人都愿意一起潜水。安排一种潜水的策略,使得最后一名选手尽量早地到达终点。

分析:考虑四个人的情况,假设游泳速度从小到达排为 a1,a2,a3,a4,最优情况有两种可能:

1.  a1,a2潜过去,a1带着瓶子回来,a1,a3潜过去,a1带着瓶子回来,a1,a3潜过去,a1带着瓶子回来,a1,a4潜过去。

2.  a1,a2潜过去,a1带着瓶子回来,a3,a4潜过去,a2带着瓶子回来,a1,a2潜过去

所以说刚看到这个问题的时候其实很难把它和贪心联系到一起,但是它实际上是可以用贪心解决的。//起码我是在知道它可以用贪心解之后才设计出这个问题的贪心           //算法的

这题的具体作法稍后再说,下面说一下我对应用贪心思想的看法

 

我感觉贪心思想的应用很灵活,很有可能一个  贪心可解的问题  我们却意识不到它是贪心可解的(如例一),要用好贪心思想,我觉得除了学好基础理论知识之外,最重要的是多去试,然后灵敏的直觉也是非常重要的。

 

接下来说例一的具体作法与证明:

为了说明方便先给几个定义:

湖的两岸 :A岸,B岸,目的:从A岸转移到B岸

集合P:当前在A岸上的人,并把他们从小到大排序成:P[1],p[2]…..

集合Q:当前在B岸上的人,并把他们从小到大排序成:Q[1],Q[2]….

所有人的集合S,按速度从小到大排序成:S[1],s[2],s[3]。。。。

性质1:从B岸带氧气瓶回A岸的人一定是Q[1]//反证法易证

性质2:某次从A岸渡至B岸的两个人有两种情况:

a.  包含p[1]

b.  不包含p[1],但此次过去B岸的两个人不在回A

b情况的证明:反证法,可构造更优的情况

性质3:若速度最快的两个人均在A岸,则下一次一定是  P[1],p[2]前往B岸

        证明:有两种情况:

a.  当前情况下的p[2]在之后的某一次与当前情况下的p[1]第一次前往B岸,此种情况与性质3中的描述等价(有点拗口,但是稍微画一下应该能懂)

b.  P[2]与p[I ](I !=1)前往B岸,此情况与性质1,性质2矛盾。

     性质4:若p[2]不与p[1]一起前往B岸,那么P[2]一定与p[3]前往B岸。

             证明:反证,此性质其实是前三个性质的推论。

     根据上述性质很容易设计出贪心算法。

     每次考虑当前A岸的情况:

1.  S[1],S[2]在A岸,则S[1],S[2]前往B岸并由S[1]带氧气瓶回A岸

2.  S[1]在A岸,S[2]在B岸

If(v[p[2]]+v[s[1]]+v[p[3]]<v[p[3]]+v[s[2]]+v[s[2]])

   则由s[1],p[2]过岸,s[1]带氧气瓶回来,s[1],s[4]过岸

Else

   P[2],p[3]过岸,s[2]带氧气瓶回来,s[1],s[2]过岸

      至此,此问题已经圆满解决。(另外,此题传说还有一个基于数学归纳法的证明方法,不过我不是很喜欢^^)

 

在上题的证明中,我并没有用到矩阵胚理论,也许在不是特别难的情况下,不用矩阵胚证明也是可行的//用矩阵胚证明实在是太抽象了^^

 

下面有一个直觉上就贪心可解的例题,也很好玩。

例二:最优布车方案

      “阶梯”型棋盘是指:每行的格子只出现在一些连续的列上,从第二行开始,每行的起始列不小于上一行的起始列数,且终止列数也不小于上一行的终止列数。

      给出一个阶梯形棋盘。放上尽量少的车,使其能控制棋盘上所有的格子,每个车能控制其同行与同列的格子。

      分析:这题贪心算法如下(易证明,但并不一定那么容易想^^):

            从上到下扫描每一行

1.  若该行上所有格子均已被控制,则不在这一行上放车。

2.  若该行上存在未被控制的格子,则在该行未被控制的格子中的最后一个放上车。

      稍微观察一下可以发现,这个问题有一个很重要的性质,明显的偏序性(严格定义在离散数学抽象代数那一章),“序”是一个很神奇的东西,许多算法基于序,许多问题一旦引入“序”之后便迎刃而解,我想这也是排序算法之所以使用广泛的原因。“序”在优化算法方面有着很大的作用(“序”的神奇之处当然远非这些,我认为值得深究^^)。

回到“贪心思想”,一旦发现了一个问题有着明显的“序”关系,那么,很有必要尝试为其设计一下贪心算法,我认为这是一个很重要的经验。(另外,此题也可以用二部图匹配来做,这个思路也很神奇~~)。

总结:贪心思想 应用很广泛,所以我只能管中窥豹见一斑。。

posted on 2012-07-26 17:02  找回失去的  阅读(539)  评论(0编辑  收藏  举报