算法法导论》P129页课后题5.3-7

suppose we want to create a random sample of the set {1,2,3,…,n}, thatis, an m-element subset S, where0≤m≤n, such that each m-subset is equally likely to be created. One waywould be to set A[i]=i for i=1,2,3,…,n, call RANDOMIZE-IN-PLACE(A), and then take just the first marray elements. This method would make n calls to the RANDOM procedure. If n is much larger than m, we can create a random samplewith fewer calls to RANDOM. Show that the following recursive procedurereturns a random m-subset S of {1,2,…,n}, in which eachm-subset is equally likely, while making only m calls to RANDOM:

RANDOM-SAMPLE(m,n)
if m == 0return ∅
elseS = RANDOM-SAMPLE(m-1, n-1)i = RANDOM(1,n)if i ∈ SS = S ∪ {n}elseS = S ∪ {i}return S

翻译过来就是:n个数随机等概率的取样m个。

该题的证明方法1:http://clrs.skanev.com/05/03/07.html

该题的证明方法2 :http://www.cnblogs.com/Jiajun/archive/2013/05/15/3080111.html

题目中其实给出了两种解决方案。

方案1:调用RANDOMIZE-IN-PLACE(A)

/**  * 创建时间:2014年8月13日 上午9:46:51  * 项目名称:Test  * @author Cao Yanfeng  * @since JDK 1.6.0_21  * 类说明:  */
public class RandomSampleTest {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubint[] array={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};int[] result=randomSample(array, 5);for (int i : result) {System.out.println(i);}}public static int[] randomSample(int[] array,int m) {randomInPlace(array);int[] result=new int[m];for (int i = 0; i <m; i++) {result[i]=array[i];}return result;}
/*《算法导论》P126页伪代码*/public static void randomInPlace(int[] array) {int n=array.length;for (int i = 0; i < n; i++) {int index=random(i, n-1);if (array[i]!=array[index]) {array[i]^=array[index];array[index]^=array[i];array[i]^=array[index];}}}public static int random(int a,int b) {return new Random().nextInt(b-a+1)+a;}
}

方案2:实现题目中的伪代码

/**

* 创建时间:2014年8月13日上午9:46:51

* 项目名称:Test

* @author Cao Yanfeng

* @since JDK 1.6.0_21

* 类说明:

*/

public classRandomSampleTest {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

int[] array={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

LinkedList<Integer>result=randomSample(array, 5);

for (Integer integer : result) {

System.out.println(integer);

}

}

public staticLinkedList<Integer> randomSample(int[] array,int m){

return sample(array, array.length, m);

}

public staticLinkedList<Integer> sample(int[] array,int n,int m) {

if (m==0) {

return newLinkedList<Integer>();

}else {

LinkedList<Integer> s=sample(array, n-1, m-1);

int i=array[random( 0, n-1)];

if (s.contains(i)) {

s.add(array[n-1]);

}else {

s.add(i);

}

return s;

}

}

/*返回闭区间的[a,b]随机数*/

public staticintrandom(inta,int b) {

return new Random().nextInt(b-a+1)+a;

}

}

方案3:赋予权重法

《算法导论》P1225.3节的Randomized algorithms中提供的第一种随机采样方法即赋予权重法。但是权重有可能出现相同情况,不推荐这种方法。

方案4:蓄水池抽样

见最后的扩展问题。

*******************************************************************************

正如题目中所言,如果n个数据选取m个样本,如果n远大于m,则应该使用方案2,仅调用m次random()函数;如果n与m差距不大,则应该使用方案1,调用n次random()函数,但是方法简单。

*******************************************************************************

扩展问题:【google面试题】给定一个数据流,其中包含无穷尽的搜索关键字(比如,人们在谷歌搜索时不断输入的关键字) 。如何才能从这个无穷尽的流中随机的选取 1000 个关键字?

参考:http://blog.csdn.net/minglingji/article/details/7984445

这也是“n个数随机等概率的取样m个”问题,但是n是未知的。采用的方式是蓄水池抽样。即:将数据流中的前1000个放入长度为1000的数组,对于1001个数,调用random(0, 1000),[0,999]闭区间内每个数被选中的概率都是1000/1001。之后对于n>1000的每个数,[0,999]闭区间内每个数被选中的概率都是1000/n。这里random被调用的次数为n-m。下面模拟一下这个过程。

/**  * 创建时间:2014年8月13日 上午9:46:51  * 项目名称:Test  * @author Cao Yanfeng  * @since JDK 1.6.0_21  * 类说明:  */
public class RandomSampleTest {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubint[] array={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};int[] result=reservoirSample(array, 5);for (int i : result) {System.out.println(i);}}/*蓄水池抽样*/public static int[] reservoirSample(int[] array,int m) {int[] reservoir=new int[m];for (int i = 0; i <array.length; i++) {if (i<m) {reservoir[i]=array[i]; }else {int temp=random(0, i);if (temp<m) {reservoir[temp]=array[i];}}}return reservoir;}
}

【算法导论学习-012】n个数随机等概率的抽样m个相关推荐

  1. 算法导论中C语言代码,算法导论-学习笔记与进度

    算法导论 阅读进度 第一部分 基础知识 第一章 计算中算法的角色 Done 1.1 算法 输入与输出 算法可以解决哪些问题 数据结构 技术 一些比较难的问题 1.2 作为一种技术的算法 效率 算法和其 ...

  2. 【算法导论学习-29】动态规划经典问题02:最长公共子序列问题(Longest common subsequence,LCS)...

    2019独角兽企业重金招聘Python工程师标准>>> 问题描述:序列X={x1,x2,-,xn},Y={y1,y2,-,yn},当Z={z1,z2-,zn}是X的严格递增下标顺序( ...

  3. 逆序对java_算法导论学习||查找逆序对

    查找逆序对很简单,自己变成就是几行,思路也是十分简单.但是题目要求用递归的方法,和合并排序很相似,网上也有很多人提供具体的程序,但是我对这种递归排序还是不能清晰得理解,所以在这里就不贴出来了,只放上了 ...

  4. 算法导论学习笔记 第7章 快速排序

    对于包含n个数的输入数组来说,快速排序是一种时间复杂度为O(n^2)的排序算法.虽然最环情况的复杂度高,但是快速排序通常是实际应用排序中最好的选择,因为快排的平均性能非常好:它的期望复杂度是O(nlg ...

  5. 算法导论学习笔记 第2章 算法基础

    本章介绍了一个贯穿本书的框架,后续的算法设计都是在这个框架中进行的. 本章通过插入排序和归并排序两种常见的算法来说明算法的过程及算法分析,在分析插入排序算法时,书中是用了循环不变式证明了算法的正确性, ...

  6. 算法导论学习笔记1_循环不变式

    循环不变式 1. 循环不变式和数学归纳法 2. 循环不变式的三条性质 3. 利用循环不变式分析插入排序 4. 练习题 2.1.3 1. 循环不变式和数学归纳法 在数学中,数学归纳法常用于证明给定命题在 ...

  7. 【算法导论学习笔记】第3章:函数的增长

    原创博客,转载请注明: http://www.cnblogs.com/wuwenyan/p/4982713.html  当算法的输入n非常大的时候,对于算法复杂度的分析就显得尤为重要,虽然有时我们能通 ...

  8. 基于visual Studio2013解决算法导论之012计数排序

     题目 计数排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...

  9. 算法导论学习笔记 第6章 堆排序

    在本章中介绍了另一种排序算法:堆排序(heapsort).与归排序一样,但不同于插入排序的是,堆排序的时间复杂度式(Onlgn).而与插入排序相同,但不同于归并排序的是,堆排序同样具有空间原址性(我理 ...

最新文章

  1. 汇编语言课本习题 p112 3.30
  2. 李宏毅深度学习——逻辑回归
  3. 白话Elasticsearch12-深度探秘搜索技术之基于multi_match + best fields语法实现dis_max+tie_breaker
  4. Solr7 安装部署 管理界面介绍
  5. [AHOI2008] 紧急集合
  6. Object o = new Object()在内存中占几个字节
  7. python鸭制作类代码_Python动态语言与鸭子类型详解
  8. NSOperation队列实实现多线程
  9. 启动SQL Server服务器以及新建连接的方法
  10. python绘制隐含波动率曲面_使用python+tushare计算期权隐含波动率并作图
  11. 阿泰,水晶报表--推拉之间
  12. 用Jplayer做的一个带动画的播放器
  13. Python与图像处理7
  14. Javascript设置滚动条向上滚动的方法;JS设置滚动条滚动的代码
  15. mysql练习答案,mysql练习语句
  16. opencv3中的glob函数读取文件夹中数据
  17. RPC论文翻译(Implementing Remote Procedure Calls)
  18. 苹果自助维修服务上线:维修工具租赁价约为321元
  19. 5.nginx访问控制
  20. 罗永浩:我不是打断你,我是讽刺你

热门文章

  1. 2 基本操作EXcel,保护与锁定单元格
  2. 产品诚可贵,质量价更高
  3. 【Linux常用指令合集】
  4. KB奇遇记(5):十大问题之战
  5. 求a的n次方,要求快速算法
  6. [IOS]如何设置section的title和改变section的背景色及样式
  7. MATLAB-等高线函数contour以及提取轮廓数据
  8. ZigBee组网详解
  9. 煤化工矿井水除氟、除砷、除总氮的技术分享交流
  10. 简述动力环境监控系统!