hadoop估算π

标签: hadoop
678人阅读 评论(0) 收藏 举报
分类:
一、hadoop不适合计算密集型的工作 

以前看过一个PPT: Hadoop In 45 Minutes or Less ,记得上面说hadoop不适合计算密集型的工作,比如计算PI后100000位小数。 

但是,前几天,我却发现了在hadoop自带的examples里,竟然有PiEstimator这个例子!!它是怎么做到的?? 


二、通过扔飞镖也能得出PI的值? 

百度一下,计算PI的方法还真不少。但在hadoop examples代码中的注释写的是:是采用 Quasi-Monte Carlo 算法来估算PI的值。 

维基百科中对Quasi-Monte Carlo的描述比较理论,好多难懂的公式。 

好在google了一把,找到了斯坦福大学网站上的一篇文章:《通过扔飞镖也能得出PI的值?》,文章很短,图文并茂,而且很好理解。 

我这里将那篇文章的重要部分截了个图: 



对上面的图再稍微解释一下: 
1、Figure2是Figure1的右上角的部分。 
2、向Figure2中投掷飞镖若干次(一个很大的数目),并且每次都仍在不同的点上。 
3、如果投掷的次数非常多,Figure2将被刺得“千疮百孔”。 
4、这时,“投掷在圆里的次数”除以“总投掷次数”,再乘以4,就是PI的值!(具体的推导过程参见原文) 

这样也能算出PI的值?相当强悍吧,呵呵。 


在这个算法中,很重要的一点是:如何做到“随机地向Figure2投掷”,就是说如何做到Figure2上的每个点被投中的概率相等。 

hadoop examples代码中,使用了Halton sequence保证这一点,关于Halton sequence,大家可以参考维基百科。 

我这里再总结一下Halton sequence的作用: 
在1乘1的正方形中,产生不重复,并且均匀的点。每个点的横坐标和纵坐标的值都在0和1之间。 

正是这样,保证了能够做到“随机地向Figure2投掷”。 


这个实际上叫做蒙特卡洛算法 

我们取一个单位的正方形(1×1) 里面做一个内切圆(单位圆) 

则 (单位正方形面积 : 内切单位圆面积) = (单位正方形内的飞镖数 : 内切单位圆内的飞镖数 )

通过计算飞镖个数就可以把单位圆面积算出来, 通过面积,在把圆周率计算出来。 

注意 

精度和你投掷的飞镖次数成正比


三、一定要用hadoop吗? 

在《通过扔飞镖也能得出PI的值?》一文中,网页中自带了一个Flash,用ActionScript来计算PI的值。 

用这种算法来估算PI值,其实是一个统计学的方法。如果要估算正确,首先要保证取样足够多(即投掷次数足够多)。但是如果是单机上运行程序,取太多的样,很容易crash your computer. 

所以,这里用hadoop的原因可以在集群上并行运行多个map任务,同时集群上的节点又非常多,这样就能够保证取到足够多的样了! 


四、hadoop examples代码解读 

上代码:
Java代码  收藏代码
  1. public void map(LongWritable offset,  
  2.                 LongWritable size,  
  3.                 OutputCollector<BooleanWritable, LongWritable> out,  
  4.                 Reporter reporter) throws IOException {  
  5.   
  6.   final HaltonSequence haltonsequence = new HaltonSequence(offset.get());  
  7.   long numInside = 0L;  
  8.   long numOutside = 0L;  
  9.   
  10.   for(long i = 0; i < size.get(); ) {  
  11.     //generate points in a unit square  
  12.     final double[] point = haltonsequence.nextPoint();  
  13.     // 1、point就是取样点,即飞镖投中的部位。这是一个x和y都是0到1的值(Halton sequence保证这一点)。此时的坐标原点在A(见Figure1)。  
  14.   
  15.     //count points inside/outside of the inscribed circle of the square  
  16.     final double x = point[0] - 0.5;  
  17.     final double y = point[1] - 0.5;  
  18.     // 2、横纵坐标各减去0.5以后,我们就可以理解成:将坐标原点从A移到了B(见Figure1)。  
  19.     if (x*x + y*y > 0.25) { // 3、根据勾股定理:x*x+y*y > 0.5*0.5(见Figure2),判断这个point是否在圆里。  
  20.       numOutside++;  
  21.     } else {  
  22.       numInside++;  
  23.     }  
  24.   
  25.     //report status  
  26.     i++;  
  27.     if (i % 1000 == 0) {  
  28.       reporter.setStatus("Generated " + i + " samples.");  
  29.     }  
  30.   }  
  31.   
  32.   //output map results  
  33.   out.collect(new BooleanWritable(true), new LongWritable(numInside));  
  34.   out.collect(new BooleanWritable(false), new LongWritable(numOutside));  
  35. }  


还需要说明的是: 
1、mapper的输出: 
Java代码  收藏代码
  1. //output map results  
  2.       out.collect(new BooleanWritable(true), new LongWritable(numInside));  // 投中的次数  
  3.       out.collect(new BooleanWritable(false), new LongWritable(numOutside));  

2、reducer,简单的对numInside进行sum操作。 

3、最后,PI的值等于: 

Java代码  收藏代码
  1. //compute estimated value  
  2.       return BigDecimal.valueOf(4// 上面图中公式中的4  
  3.       .setScale(20)     //精度  
  4.           .multiply(BigDecimal.valueOf(numInside.get()))    // 投中的次数  
  5.           .divide(BigDecimal.valueOf(numMaps))          // mapper的数量  
  6.           .divide(BigDecimal.valueOf(numPoints));       // 每个mapper投掷多少次  


总共投掷的次数 = mapper的数目*每个mapper投掷的次数 

PI = 4 * 投中的次数 / 总共投掷的次数 


五、小结 

hadoop(mapreduce)确实不适合做计算密集型的工作,尤其是下一步计算依赖于上一步的计算结果的时候。 

但是hadoop的examples中的计算PI的方法并不属于这一类,而是采用大量采样的统计学方法,还是属于数据密集型的工作。 

回到本文开头提到的PPT中,里面写的是“hadoop不适合计算PI小数点后1000000位小数”,而hadoop的example只是“估算PI的值”,二者并不是同一项任务。 



附:运行hadoop估算PI的命令 

Java代码  收藏代码
  1. hadoop jar $HADOOP_HOME/hadoop-*-examples.jar pi 100 100000000  

后面2个数字参数的含义: 
第1个100指的是要运行100次map任务 
第2个数字指的是每个map任务,要投掷多少次 

2个参数的乘积就是总的投掷次数。 

我运行的结果: 
Job Finished in 7492.442 seconds 

Estimated value of Pi is 3.14159266720000000000 

转载出处:http://thinkinginhadoop.iteye.com/blog/710847

查看评论

用hadoop计算PI值

摘要:最近研究hadoop的一个例子,计算PI值,本以为hadoop不适合这种密集型的计算,却发现了在hadoop自带的examples里,竟然有PiEstimator这个例子,于是深入研究一下,首先...
  • minglaihan
  • minglaihan
  • 2014-08-30 10:19:39
  • 2673

【MapReduce开发】计算PI

MapReduce无法进行递归和迭代式的计算,所以目前基于MapReduce计算PI的算法只有一种,就是Stanford在一篇论文里提到过的一种掷飞镖计算方法。原文我在网上没有找到,所以就把网友的文章...
  • Amber_amber
  • Amber_amber
  • 2015-08-13 15:49:07
  • 1740

搭建Hadoop集群,一个月6T的数量需要几台服务器

配置几个namenode,几个datanode,namenode和datanode怎么部署,内存与硬盘大小。 最好是两个做成HA 关于硬盘:     6T的数据容量,看你副本数量设置是...
  • YYDU_666
  • YYDU_666
  • 2017-12-08 14:03:58
  • 342

计算PI(π)的几种方法

计算π的方法 一、蒙特卡罗法 这种方法是一种利用计算机随机数的功能基于“随机数”的算法,通过计算落在单位圆内的点与落在正方形内的 点的比值求PI。 由于图形的对称性,我们靠考虑该图...
  • birdreamer
  • birdreamer
  • 2018-03-13 21:15:23
  • 326

使用MapReduce计算Pi

总体思路核心思想是向以(0,0),(0,1),(1,0),(1,1)为顶点的正方形中投掷随机点。统计(0.5,0.5)为圆心的单位圆中落点占总落点数的百分比,即可算出单位圆的面积Pi/4,然后乘以4即...
  • mrbcy
  • mrbcy
  • 2017-03-11 23:48:29
  • 465

hadoop3.0

 Apache  hadoop 项目组最新消息,hadoop3.x以后将会调整方案架构,将Mapreduce 基于内存+io+磁盘,共同处理数据。 其实最大改变的是hdfs,hdf...
  • u010176505
  • u010176505
  • 2016-08-02 10:09:30
  • 420

第118讲:Hadoop内存需求量及Namenode内存使用详解学习笔记

第118讲:Hadoop内存需求量及Namenode内存使用详解学习笔记 本期内容: 1.hadoop的内存使用 2.namenode内存使用详解 namenode内存大小涉及到集群的规模。 ...
  • slq1023
  • slq1023
  • 2015-10-25 21:32:50
  • 3142

用hadoop计算PI值

一、计算PI值的方式与原理       百度一下,计算PI的方法还真不少。但在hadoop examples代码中的注释写的是:是采用 Quasi-Monte Carlo 算法来估算PI的值。  ...
  • qq_20545159
  • qq_20545159
  • 2016-01-01 18:43:31
  • 1120

计算PI值

计算PI值 一个PI值计算的算法。 分析该算法。 实现该算法。 算法:PI/2=1/3 + 1/3 * 2/5 + 1/3 * 2/5 * 3/7 + …….+ 1/3* ……* n/(n+1) ...
  • gd007he
  • gd007he
  • 2017-03-13 22:15:42
  • 387

第十天:估算活动持续时间,类比估算,参数估算,自下而上估算,三点估算解析表

  • toto1297488504
  • toto1297488504
  • 2016-07-07 22:19:21
  • 4282
    个人资料
    等级:
    访问量: 30万+
    积分: 3323
    排名: 1万+
    最新评论