算法导论5.1 雇用问题



第五章围绕概率分析,随机算法,概率与期望展开了一系列有趣的讨论,其中许多有趣概率习题。


------------------------------------------------------------------------------------------------------------------------------------------------



雇佣问题描述:

假设你要雇佣一个新的办公室助理,雇佣代理每天想你推荐一个应聘者(连续推荐n个),你面试这个人,如果这个应聘者比目前的办公室助理更优秀,你就会辞掉当前的办公室助理,然后聘用这个新的。面试一个人需付给雇佣代理一笔费用,聘用办公助理也需要费用。

假设面试费用为Ci,雇佣的费用为Ch,假设整个过程中雇佣了m次,于是总的费用是 nCi+mCh。由于n是固定值,总费用的变化取决于m值。

这个场景用来当做一般计算范式的模型,通常情况下我们需要检查队列中的每个成员,并且维护一个目前的获胜者,来找出序列中的最大或最小值。雇佣问题是对哪一个成员当前获胜的更新频繁程度建立模型。


最坏情况

最坏情况下,我们雇佣了每一个应聘者,m=n。


HIRE-ASSISTANT(n)
1  best  0     ® candidate 0 is a least-qualified dummy candidate
2  for i  1 to n
3       do interview candidate i
4          if candidate i is better than candidate best
5             then best  i
6                  hire candidate i


注意n个人总是要全部面试完的,所以面试的费用是一定的,关键在于雇佣几次是不确定的,取决于n个人的排名及先后顺序。


---------------------------------------------------------------------------------------------------------------------------------------------------




概率分析

事实上,我们既不能得知应聘者出现的顺序,也不能控制这个顺序,因此我们使用概率分析。概率分析就是在问题的分析中使用概率技术。为了使用概率分 析,必须使用关于输入分布的知识或者对其做假设,然后分析算法,计算出一个期望的运行时间

有些问题,我们对所有可能的输入集合做某种假设。对于其他问题,可能无法描述一个合理的输入分布,此时就不能使用概率分析方法。

在雇佣问题中,可以假设应聘者是以随机顺序出现的。假设可以对任何两个应聘者进行比较并确定哪个更优;换言之,在所有的应聘者之间存在这一个全序关 系。因此可以使用从1到n的唯一号码来标志应聘者的优秀程度。用rank(i)来表示应聘者i的名次。这个有序序 列<rank(1),rank(2),..., rank(n)>是序列<1,2,...,n>的一个排列。说应聘者以随机的顺序出现,就等于说这个排名列表是1到n的n!中排列中的 任何一个,每种都以相等的概率出现。


随机算法

在许多情况下,我们对输入分布知识知之甚少;即使知道关于输入分布的某些信息,也无法对这种分布建立模型。然而通过使一个算法中的某些部分的行为随机化,就常常可以利用概率和随机性作为算法设计和分析的工具

比如在雇佣问题中,如果雇佣代理给我们一份应聘者的名单,每天我们随机地挑选一个应聘者进行面试,从而确保了应聘序列的随机性。

更一般地,如果一个算法的行为不只有输入决定,同时也由随机数生成器所产生的数值决定,则称这个算法是随机的



由以上描述可知概率分析和随机算法的区别

概率分析是对输入做假设,假设输入服从某种分布(例如假设输入是随机的),然后根据假设的概率前提来分析期望情况。

而随机算法是通过一个算法来重新排列输入,使得输入变的随机化。




--------------------------------------------------------------------------------------------------------------------------------------------------



几道习题还是相当有难度的,网上可以搜到相关的解答


练习5.1.2

假设Random(a,b)以相同概率返回a到b之间的任何一个数字,描述Random(a,b)过程的一种实现,它只调用现有实现Random(0,1)。作为a和b的函数,你的程序的期望运行时间是多少?假设Ramdom(0,1)的运行时间是常数。


http://bbs.chinaunix.net/thread-1192193-1-1.html    上有一个讨论

思路1:

这个题目相当于在能随机生成 0, 1 的前提下,要求随机生成 n 个整数。(每个数生成的概率相等
把要生成的数标记为 0,1,2,..., n-1
取最小的 m,使得 2^m >= n-1
通过随机生成 0,1 的函数生成一个  m 比特整数(随机生成每一位),这样能随机生成 [0, 2^m) 内的整数。
随机生成一个 [0,2^m) 中的整数,如果这个数大小在 [0,n-1] 内,则取这个数为结果。
如果这个数在 [0,n-1] 外,则丢弃它,重新生成一个。


思路2:

k = b-a+1,如果k为偶数,则将S均分成两组,通过一次R(0,1)来淘汰其中一组;如果S为奇数, 则用上述方法来分组,将占多数的一组淘汰。可以证明这个算法后也是正确的。只要在某一轮的测试中R(0,1)的输出为全0或全1,问题的规模就可以缩小一 半。

思路3:

或者用二分的方式,根据Ramdom(0,1)是0还是1进入[a,b]区间的前半部分或者后半部分,这样同样面临如果区间长度不是2的整数次方,会导致每个数生成的概率不一样,应该再做一点处理,扩大生成的范围,像思路1中把不是范围内的数丢掉。


 -------------------------------------------------------------------------------------------------------------------------------------------------

练习5.1.3

假设你希望以各1/2的概率输出0和1。你可以自由使用一个输出0或1的过程 BIASED-RANDOM。它以概率p输出1,以概率1-p输出0,其中0<p<1,但是你并不知道p的值。给出一个利用BIASED- RANDOM作为子程序的算法,返回一个无偏向的结果。你的算法的期望运行时间是多少?

分析:设计的思路是利用对称性。 假设有两个基于BIASED-RANDOM的伯努利试验序列A、B。每个试验序列都会产生0,1值序列;每一轮A和B各进行一次,如果该轮试验的结果是 ai>bi(即ai=1,bi=0)则算法结束,结果为1;如果ai<bi则算法结束结果为0;如果ai=bi则开始下一轮迭代。

由于每一轮试验都是独立的,所以只要能够证明每一轮在得出结果的条件下,得出1和得出0的概率相等就可以了

while TRUE
do
x = BIASED-RANDOM
y = BIASED-RANDOM
if x != y
then return x

得出1的概率是p*q    (x得出1,y得出0)

得出0的概率是q*p  (x得出0,y得出1)

精妙!



-------------------------------------------------------------------------------------------------------------------------------------------------

总结:

第五章有许多有意思的习题,值得思考


参考:

算法导论

http://blog.csdn.net/longhuihu/article/details/5864442   csdn上某人的算法导论学习笔记

http://bbs.chinaunix.net/thread-1192193-1-1.html

posted @ 2011-08-11 11:31  jinmengzhe  阅读(3838)  评论(0编辑  收藏  举报