码迷,mamicode.com
首页 > 其他好文 > 详细

看spark示例代码如何求的PI

时间:2015-08-15 16:41:52      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:python   spark   pi   

以前也知道蒙特卡洛投针求PI,今天安装spark,安完先要试试他自带的几个小程序看看能不能用,我主要会用python写程序,也就是pyspark所以在spark里的examples目录深处找python的文件夹,里面的pi.py就是。看了一下源码是这样的:

import sys
from random import random
from operator import add

from pyspark import SparkContext


if __name__ == "__main__":
    """
        Usage: pi [partitions]
    """
    sc = SparkContext(appName="PythonPi")
    partitions = int(sys.argv[1]) if len(sys.argv) > 1 else 2
    n = 100000 * partitions

    def f(_):
        x = random() * 2 - 1
        y = random() * 2 - 1
        return 1 if x ** 2 + y ** 2 < 1 else 0

    count = sc.parallelize(range(1, n + 1), partitions).map(f).reduce(add)
    print("Pi is roughly %f" % (4.0 * count / n))

    sc.stop()


意思就是调用者传个参数进去也就是投针次数,传3他就投30万次,然后他要造成在一个边长为2的正方形里等概率投针的模拟。这里random()产生0~1之间的数,“*2”就是0~2之间等概率的数,再“-1”x与y就变成-1到1之间等概率的数,(x,y)就是在边长为2的正方形里均匀分布的点,正方形的内切圆面积就是PI,距原点小于1的就在园内,由“PI/4 = 园内点数/总点数”可以估计PI

技术分享


跑了一下效果还是不错的,结果每次都不一样但在3.14附近,当然他用MapReduce,我也可以写一个不用分布计算的嘛,然后拿C++写了一个:

#include <iostream>
#include <cmath>
#include <stdlib.h>
using namespace std;

int main()
{
    int n;
    cout<<"键入模拟投针次数:\n";
    cin>>n;
    int in_circle_cnt=0;
    for(int i=0;i<=n;i++)
    {
        double x=(double(rand()%1000)/1000.0)*2-1;
        double y=(double(rand()%1000)/1000.0)*2-1;
        double dist=x*x+y*y;
        if(dist<=1.0)
            in_circle_cnt++;
    }
    cout<<"PI值约为:"<<4.0*double(in_circle_cnt)/double(n)<<endl;
    return 0;
}


意思是到了,效果很差模拟上亿次也不太好,而且相同输入每次都一样结果,当然了,差别就在随机函数上了,我C++里用的是C标准库的伪随机表,而python的随机函数random()要优秀的多,才能尽量造成随机且均匀分布的感觉。



版权声明:本文为博主原创文章,未经博主允许不得转载。

看spark示例代码如何求的PI

标签:python   spark   pi   

原文地址:http://blog.csdn.net/xiaopangxia/article/details/47681773

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!