|
众所周知,在一个正方形上抛飞镖,假设有一个半径为正方形边长的1/4圆,则抛的飞镖在1/4圆内的概率为1/4圆面积除以正方形面积,即(pi*r^2 /4)/r^2,假设抛飞镖在圆内的概率为n,则pi=4n,通过蒙特卡洛模拟则可算出一个较接近的pi。由于频率是不断接近概率的,因此必须抛很多次飞 镖,这里采用了Hadoop去模拟。
1. [代码]MapReduce的mainRunner忽略,大家可根据需要改下输入输出KeyValue的意义
02 | public class PieMapper extends |
03 | Mapper<IntWritable, LongWritable, LongWritable, LongWritable> { |
04 | private Random random = new Random(); |
06 | protected void map(IntWritable key, LongWritable value, Context context) |
07 | throws IOException, InterruptedException { |
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) { |
16 | context.write(value, new LongWritable(inside)); |
19 | // 输入为第几行(忽略)+本行所算的抛飞镖次数 |
22 | public class PieReducer extends |
23 | Reducer<LongWritable, LongWritable, LongWritable, DoubleWritable> { |
25 | protected void reduce(LongWritable key, Iterable<LongWritable> values, |
26 | Context context) throws IOException, InterruptedException { |
29 | for (LongWritable value : values) { |
31 | inside += value.get(); |
33 | context.write(key, new DoubleWritable( |
34 | 4 * (inside / total))); |
38 | // 代码应该比较清楚,输出为抛的总次数所对应的算出的圆周率,可以用来对比抛N次所得到的精度。当然Double是非常不精确的,要想更精确则需要重新实现大的浮点类型 |
|
|
|