用Hadoop扔飞镖算Pi——献给圆周率日

众所周知,在一个正方形上抛飞镖,假设有一个半径为正方形边长的1/4圆,则抛的飞镖在1/4圆内的概率为1/4圆面积除以正方形面积,即(pi*r^2 /4)/r^2,假设抛飞镖在圆内的概率为n,则pi=4n,通过蒙特卡洛模拟则可算出一个较接近的pi。由于频率是不断接近概率的,因此必须抛很多次飞 镖,这里采用了Hadoop去模拟。

 

1. [代码]MapReduce的mainRunner忽略,大家可根据需要改下输入输出KeyValue的意义    

01 // Mapper
02 public class PieMapper extends
03         Mapper<IntWritable, LongWritable, LongWritable, LongWritable> {
04     private Random random = new Random();
05     @Override
06     protected void map(IntWritable key, LongWritable value, Context context)
07             throws IOException, InterruptedException {
08         long inside = 0;
09         for (int i = 0; i < value.get(); i++) {
10             double a = random.nextDouble();
11             double b = random.nextDouble();
12             if ((a * a + b * b) <= 1) {
13                 inside++;
14             }
15         }
16         context.write(value, new LongWritable(inside));
17     }
18 }
19 // 输入为第几行(忽略)+本行所算的抛飞镖次数
20  
21 // Reducer
22 public class PieReducer extends
23         Reducer<LongWritable, LongWritable, LongWritable, DoubleWritable> {
24     @Override
25     protected void reduce(LongWritable key, Iterable<LongWritable> values,
26             Context context) throws IOException, InterruptedException {
27         long total = 0;
28         long inside = 0;
29         for (LongWritable value : values) {
30             total += key.get();
31             inside += value.get();
32         }
33         context.write(key, new DoubleWritable(
34                 4 * (inside / total)));
35     }
36 }
37  
38 // 代码应该比较清楚,输出为抛的总次数所对应的算出的圆周率,可以用来对比抛N次所得到的精度。当然Double是非常不精确的,要想更精确则需要重新实现大的浮点类型

你可能感兴趣的:(mapreduce,hadoop)