看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()要优秀的多,才能尽量造成随机且均匀分布的感觉。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值