韶关建网站国外设计公司网站
韶关建网站,国外设计公司网站,wordpress博客发布软件,十大网站建设公司公众号#xff1a;编程驿站
圆周率的常见几种求解算法#xff0c;包括但不仅仅包含特卡洛模拟、割圆法和公式法。本文讲解这几种算法的实现流程。
1. 蒙特卡洛模拟算法
假设有一个半径为1的圆#xff0c;如图所示。先绘制一个半径为1的圆。则图中阴影部分#xff08;1/4…公众号编程驿站
圆周率的常见几种求解算法包括但不仅仅包含特卡洛模拟、割圆法和公式法。本文讲解这几种算法的实现流程。
1. 蒙特卡洛模拟算法
假设有一个半径为1的圆如图所示。先绘制一个半径为1的圆。则图中阴影部分1/4圆的面积就等于π/4。 再绘制出一个正方形可以看出它的面积是 1 。通过这种方式就能够获取到正方形面积和阴影部分面积的一个比例。如此可得到正方形和阴影面积的比例关系1:π/4。这是通过数学上提供的计算面积的公式得到的一个比例。
另外的话呢我们可以生成很多点。然后把它们随机、均均匀的把平铺到正方形里面去。这时候呢我们可以认为这些点呢模拟出正方形的面积。另外我们需要计算出有哪些点落在了阴影部分。这种方式也能够获取到正方形和阴影部分面积的比例。这个比例和我们前面通过数学公式所求出的比例呢是一种恒等于的关系我们利用这种恒等关系就能够很轻松的获取到这个圆周率。
下面我们看一下这个代码应该如何实现
第一步利用随机函数产生很多点横坐标的值x和纵坐标的值y都在0~1之间随机、均匀散满在正方形内。且统计出散落在阴影部分点的数量。获取正方形内点的数量和阴影部分点的数量的比例。显然此比例和前面通过公式计算两者面积的比例具有恒等于关系。通过此关系便可计算出圆周率。
#include iostream
#include cstdlib
#include ctime
#include cmath
using namespace std;
int main(int argc, char** argv) {//随机种子srand( time(0) );double num10000000;double circle0;//random 伪随机数算法for(int i1; inum; i) {double x rand() / double(RAND_MAX);double yrand() / double(RAND_MAX);if( x*xy*y 1 ) {circle;}}double pi4*circle / num;coutpi;return 0;
}2. 割圆法
例如假设一个半径为1的圆在圆中有一个内接6边形如图所示。该内接六边形的弦长y1周长d6*y1则π的近似值pi6*y/23。 可以通过内接 12,24,48……正多边形求出精度更高的圆周率。
如下图把圆切割成六边形根据等边三角形的特征可知六边形的边长y1。 如下图把圆切割成正12边形。 因为ABD为直角三角形可得AB2AD2-BD21-1/43/4所以ABsqrt(3/4)。
又因为BCD也为直角三角形可得y2BD2CB21/4(1-AB)21/41-2*sqrt(3/4)3/42-sqrt(3)。
所以pi6*sqrt( 2-sqrt(3) )。
#include bits/stdc.h
using namespace std;
int main () {int i,n,s6;double y1;cout输入切割次数:endl;cinn;for(int i0; in; i) {printf(第%d次切割,为%d边,PI%.24f\n,i,s,s/2*sqrt(y));s*2;//弦长的平方值 y2-sqrt(4-y); }return 0;
}3. 公式法
求解圆周率的公式常见的有如下三个
3.1 公式一 本质是累乘问题关键是找到参与累乘数字的之间的规律。这里有两种规律。
通过观察可以发现后一个分数的分母是前一个分数的分子加1后一个分数的分子是前一个分数的分母加一。
代码实现
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res1;int n;cinn;double fm1,fz2;for(int i0;in;i){res*fz/fm;//先存储前一个分数的分母int tfm;//后一个分数的分母是前一个分数的分子加1fm fz1;//后一个分数的分子是前一个分数的分母加1fzt1; }coutres*2;return 0;
}给参与累乘的数字编号会发现当累乘数字的编号为偶数时改变分数的分母为下一个奇数当编号为奇数时改变分子为下一个偶数。 代码实现
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res1;int n;cinn;double fm1,fz2;res*fz/fm;for(int i2; in; i) {if( i%20 )fm2;else fz2;res*fz/fm;}coutres*2;return 0;
}3.2 公式二 我们可以把它当成一个累加的问题但是在累加的时候又包括有这个累乘的算法这里我们有两种思考方案。
第一种方式我们就把相乘当成雷加的一个内嵌的运算式子就是说用循环嵌套。
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res1;int n;cinn;for(int i1;in;i){double lc1;double fm3;for( int j1;ji;j ){lc*j/fm;fm2;}reslc;}coutres*2;return 0;
}第二种方案本质上还是一个累加的问题累加的时候它要获得一个累乘的效果。一个累乘的值在不停的变化所以这里我就会声明一个变量。变量用来存储累乘的结果。
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res1,lc1;int n;cinn;double fm3; //分母for(int i1;in;i){ //i 分子 lc*1/fm;reslc;fm2;}coutres*2;return 0;
}3.3 公式三 此题也有两种方案使用二层循环和一层循环。
二层循环。外层循环实现累乘问题内层循环每次重次计算分母。
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res2;int n;cinn;for(int i1;in;i){double fmsqrt(2);for( int j1;ji;j){fmsqrt( 2fm );}res*2/fm;}coutres;return 0;
}一层循环。下一次的分母为2减去上一次分母然后开平方根。
#include bits/stdc.h
using namespace std;
int main(int argc, char** argv) {double res2;int n;cinn;double fmsqrt(2);for(int i0;in;i){res*2/fm;fmsqrt( 2fm );}coutres; return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/88846.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!