Hadoop下MapReduce實現Pi值的計算


Hadoop自帶的例子中,有一個計算Pi值的例子。

 

這個程序的原理是這樣的。假如有一個邊長為1的正方形。以正方形的一個端點為圓心,以1為半徑,畫一個圓弧,於是在正方形內就有了一個直角扇形。在正方形里隨機生成若干的點,則有些點是在扇形內,有些點是在扇形外。正方形的面積是1,扇形的面積是0.25*Pi。設點的數量一共是n,扇形內的點數量是nc,在點足夠多足夠密集的情況下,會近似有nc/n的比值約等於扇形面積與正方形面積的比值,也就是nc/n= 0.25*Pi/1,即Pi = 4*nc/n。

 

在正方形內生成的樣本點越多,計算Pi值越精確,這樣,這個問題就很適合用Hadoop來處理啦。假設要在正方形內生成1000萬個點,可以設置10個Map任務,每個Map任務處理100萬個點,也可以設置100個Map任務,每個Map任務處理10萬個點。

 

package mapreduce1;
/*
 *  @create by 劉大哥
 *  2019年9月3日
   *       利用MapReduce計算pi值
 * */
import java.io.IOException;  
import java.util.StringTokenizer;  
import org.apache.hadoop.fs.Path;  
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 PI.Pi;  


    public class WordCount {  
        public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {  
            Job job = Job.getInstance();  
            job.setJobName("WordCount");  
            job.setJarByClass(WordCount.class);  
            job.setMapperClass(doMapper.class);
            job.setReducerClass(doReducer.class);  
            job.setOutputKeyClass(Text.class);  
            job.setOutputValueClass(IntWritable.class);  
            Path in = new Path("hdfs://192.168.100.129:9000/user/hadoop/p1i.txt");   //輸入路徑
            Path out = new Path("hdfs://192.168.100.129:9000/user/hadoop/out_pi1");  //輸出路徑
            FileInputFormat.addInputPath(job, in);  
            FileOutputFormat.setOutputPath(job, out);  
            System.exit(job.waitForCompletion(true) ? 0 : 1);  
        }  
        public static class doMapper extends Mapper<Object, Text, Text, IntWritable>{  
            private static final IntWritable one = new IntWritable(1);  
            @Override  
            protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {  
                String line =  value.toString();    
                String word = line.toString();         //讀取每個map的數值
                //System.out.println(word);
                int num = Integer.parseInt(word);      //轉化為int類型 
                //System.out.println(num);
                int[] base = {2,5};
                Pi test = new Pi(base);  
                int a= 0;         // 是否在扇形區域內的標志符  1:在扇形區域內 2:不在扇形區域內
                int count = 0;  // 統計在扇形區域內點的個數
                for(int x = 0; x < num; x++){
                    double[] t = test.getNext();
                    if(t[0]*t[0]+t[1]*t[1]<1) {  //在扇形區域內
                        a=1;
                        count++;                 //在扇形區域內的個數加+
                    }
                    else {                       //不在扇形區域內
                        a=2;
                    }
                
                }
                double result= count*4.00000000/num;    //每個map計算出pi的值
                String strresule = String.valueOf(result); 
                Text textresult = new Text();              /*轉換類型為Text */
                textresult.set(strresule);                
                context.write(textresult, one);         //寫入
            }  
        }  
        public static class doReducer extends Reducer<Text, IntWritable, Text, IntWritable>{   //reduce 整合輸出
            private IntWritable result = new IntWritable();  
            @Override  
            protected void reduce(Text key, Iterable<IntWritable> values, Context context)  
            throws IOException, InterruptedException {  
            int sum = 0;  
            for (IntWritable value : values) {  
                sum += value.get();  
            }  
                result.set(sum); 
                context.write(key, result);  
            }  
        }  
    }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM