Hadoop实例之Java代码实现利用MapReduce求π值
生活随笔
收集整理的這篇文章主要介紹了
Hadoop实例之Java代码实现利用MapReduce求π值
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
需求:假如有一個(gè)邊長為1的正方形。以正方形的一個(gè)端點(diǎn)為圓心,以1為半徑,畫一個(gè)圓弧,于是在正方形內(nèi)就有了一個(gè)直角扇形。在正方形里隨機(jī)生成若干的點(diǎn),則有些點(diǎn)是在扇形內(nèi),有些點(diǎn)是在扇形外。正方形的面積是1,扇形的面積是0.25*Pi。設(shè)點(diǎn)的數(shù)量一共是n,扇形內(nèi)的點(diǎn)數(shù)量是nc,在點(diǎn)足夠多足夠密集的情況下,會近似有nc/n的比值約等于扇形面積與正方形面積的比值,也就是nc/n= 0.25*Pi/1,即Pi = 4*nc/n。
首先是隨機(jī)生成點(diǎn)的問題,利用Halton序列算法隨機(jī)生成的樣本點(diǎn)十分均勻,計(jì)算精度較高,效果比較好。
下面是網(wǎng)上找到的一個(gè)利用Halton序列算法隨機(jī)生成的樣本點(diǎn)的代碼:
?
public class Pi {static int digit = 40;private int[] bases= new int[2];private double[] baseDigit = new double[2];private double[][] background = new double[2][digit];private long index;Pi(int[] base) {bases = base.clone();index = 0;for(int i=0; i<bases.length; i++) {double b = 1.0/bases[i];baseDigit[i] = b;for(int j=0; j<digit; j++) {background[i][j] = j == 0 ? b : background[i][j-1]*b;}}}double[] getNext() {index++;double[] result = {0,0};for(int i=0; i<bases.length; i++) {long num = index;int j = 0;while(num != 0) {result[i] += num % bases[i] * background[i][j++];num /= bases[i];}}return result;}public static void main(String[] args) {int[] base = {2,5};Pi test = new Pi(base);for(int x = 0; x < 100; x++){double[] t = test.getNext();System.out.println(t[0] + "\t" + t[1]);}}}?
下面是計(jì)算π值的代碼:
package mapreduce;import java.io.IOException;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.DoubleWritable; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import mapreduce.Pi;//下面生成隨機(jī)數(shù)的時(shí)候需要這個(gè)類,該類即上面那部分代碼/*** * @author sakura* 2019.9.3* 利用MapReduce計(jì)算π值**/ public class CalPI {public static class PiMapper extends Mapper<Object, Text, Text, IntWritable>{int number=0; //定義一個(gè)變量,用來存放一共生成的點(diǎn)數(shù)//讀取文件,每一行都是一個(gè)map 本程序讀取的文件為十行,每行都是100000public void map(Object key, Text value, Context context) throws IOException, InterruptedException {int pointNum = Integer.parseInt(value.toString());//將讀取到的那一行賦值給pointNumnumber=number+pointNum;//將總點(diǎn)數(shù)賦值給numberint[] base = {2,5};//生成隨機(jī)點(diǎn)所用Pi test = new Pi(base);//生成隨機(jī)點(diǎn)所用for(int x = 0; x < number; x++){ //循環(huán)生成隨機(jī)點(diǎn)double[] t = test.getNext();//隨機(jī)生成點(diǎn),并將坐標(biāo)存入數(shù)組System.out.println(t[0] + "\t" + t[1]);//控制臺輸出隨機(jī)點(diǎn)的坐標(biāo)IntWritable result = new IntWritable(0); //定義輸出值if((t[0]*t[0]+t[1]*t[1])<=1)//判斷生成的點(diǎn)是否在扇形面積內(nèi) {result = new IntWritable(1);//如果在,將輸出值賦值為1 }value.set(String.valueOf(number));//定義輸出鍵,輸出鍵為當(dāng)前生成點(diǎn)的總數(shù)context.write(value, result);//寫入 }}}public static class PiReducer extends Reducer<Text,IntWritable,Text,DoubleWritable> {private DoubleWritable result = new DoubleWritable();//聲明輸出值public void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException {double pointNum =Double.parseDouble(key.toString());//獲取輸入的鍵double sum = 0;//定義總數(shù)for (IntWritable val : values) {//循環(huán)從values里取值,累加和賦值給sumsum += val.get();}result.set(sum/pointNum*4);//將計(jì)算得到的π值賦值給result context.write(key, result);//將鍵值,即生成點(diǎn)總數(shù),和result,即計(jì)算得到的π值作為一個(gè)鍵值對寫入context }}public static void main(String[] args) throws Exception {Configuration conf = new Configuration();Job job = Job.getInstance(conf,"calculate pi");job.setJarByClass(CalPI.class);job.setMapperClass(PiMapper.class);job.setReducerClass(PiReducer.class);job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(IntWritable.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(DoubleWritable.class);Path in = new Path("hdfs://192.168.68.130:9000/user/hadoop/nai.txt"); //讀入文件地址Path out = new Path("hdfs://192.168.68.130:9000/user/hadoop/output4"); //輸出文件地址,output4不能存在 FileInputFormat.addInputPath(job, in);FileOutputFormat.setOutputPath(job, out);System.exit(job.waitForCompletion(true) ? 0 : 1); }}?
轉(zhuǎn)載于:https://www.cnblogs.com/sakura--/p/11455467.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Hadoop实例之Java代码实现利用MapReduce求π值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea中修改代码大小设置
- 下一篇: openresty开发系列37--ngi