实验5 蒙特卡罗法求PI及排序算法
数学建模蒙特卡洛模拟方法详细案例

数学建模蒙特卡洛模拟方法详细案例
数学建模中的蒙特卡洛模拟方法是一种基于随机数生成和概率统计的方法,可以用于求解各种复杂的问题。
下面是一个详细的案例,以帮助你更好地理解蒙特卡洛模拟方法的应用。
案例:估计圆周率
假设我们要求解圆周率(π)的值。
我们可以使用蒙特卡洛模拟方法来估计π的值。
1. 定义问题的概率模型:在这个案例中,我们使用一个简单的概率模型,即在一个边长为1的正方形内随机生成点,并计算这些点到正方形中心的距离。
2. 生成随机数:使用随机数生成器生成一系列的随机数,这些随机数代表点在正方形内的坐标。
3. 计算点到中心的距离:对于每个生成的点,计算它到正方形中心的距离。
4. 计算落在圆内的点的比例:将落在半径为1的圆内的点的数量除以总的点数。
这个比例近似于圆的面积与正方形的面积之比,也就是π/4。
5. 通过比例求解π:将步骤4中的比例乘以4,即可得到π的近似值。
通过多次重复上述步骤并取平均值,可以进一步提高估计的准确性。
需要注意的是,蒙特卡洛模拟方法是一种基于随机数生成和概率统计的方法,其结果具有一定的随机性和误差。
因此,在应用蒙特卡洛模拟方法时,需要选择合适的随机数生成器和概率模型,以确保结果的准确性和可靠性。
21——matlab——用蒙特卡罗方法计算pi的值

用蒙特卡罗( Monte Carlo ) 投点法计算 的值程序:n=10000;m=0; a=2;for i=1:nx=rand(1)*a/2;y=rand(1)*a/2;if x^2+y^2<=(a/2)^2m=m+1;endendfprintf('蒙特卡罗投点法计算的pi为:%f\n',4*m/n)结果:蒙特卡罗投点法计算的pi为:3.117200蒙特卡罗投点法计算的pi为:3.132400蒙特卡罗投点法计算的pi为:3.165600蒙特卡罗投点法计算的pi为:3.135200蒙特卡罗投点法计算的pi为:3.146800蒙特卡罗投点法计算的pi为:3.140400蒙特卡罗投点法计算的pi为:3.114800蒙特卡罗投点法计算的pi为:3.117200 蒙特卡罗投点法计算的pi为:3.154800 蒙特卡罗投点法计算的pi为:3.140400 蒙特卡罗投点法计算的pi为:3.121200 蒙特卡罗投点法计算的pi为:3.134400 蒙特卡罗投点法计算的pi为:3.122800 蒙特卡罗投点法计算的pi为:3.127600 蒙特卡罗投点法计算的pi为:3.147200 蒙特卡罗投点法计算的pi为:3.145200 蒙特卡罗投点法计算的pi为:3.158400 蒙特卡罗投点法计算的pi为:3.147600 蒙特卡罗投点法计算的pi为:3.147600 蒙特卡罗投点法计算的pi为:3.146400 蒙特卡罗投点法计算的pi为:3.112000 蒙特卡罗投点法计算的pi为:3.180000 蒙特卡罗投点法计算的pi为:3.120000 蒙特卡罗投点法计算的pi为:3.153600 蒙特卡罗投点法计算的pi为:3.144000 蒙特卡罗投点法计算的pi为:3.148000 >>。
用蒙特卡罗方法计算π值实验报告

本科生实验报告实验课程蒙特卡罗模拟学院名称核技术与自动化工程学院专业名称核技术及应用学生姓名王明学生学号**********指导教师邮箱****************实验成绩二〇一七年九月二〇一八年一月实验一、选择一种编程语言模拟出π的值一、实验目的1、理解并掌握蒙特卡罗模拟的基本原理;2、运用蒙特卡洛思想解决实际问题;3、分析总结蒙特卡洛解决问题的优缺点。
二、实验原理用蒙特卡洛思想计算π的值分为如下几部:第一步构建几何原理:构建单位圆外切正方形的几何图形。
单位圆的面积为S0=π,正方形的面积S1=4;第二步产生随机数进行打把:这里用MATLAB产生均匀随机数。
分别生产均匀随机数(x,y)二维坐标。
X,y的范围为-1到1.总共生成N个坐标(x,y).统计随机生成的坐标(x,y)在单位圆内的个数M。
第三步打把结构处理:根据S0/S1=M/N计算出π的值。
因此π=4*M/N。
第四步改变N的值分析π的收敛性:总数1000开始打把,依次增长10倍到1百万个计数。
三、实验内容1、用matlab编写的实验代码,总计数率为1000。
zfx_x=[1,-1,-1,1,1];zfx_y=[1,1,-1,-1,1];plot(zfx_x,zfx_y)axis([-3 3 -3 3]);hold on;r=1; theta=0:pi/100:2*pi;x=r*cos(theta); y=r*sin(theta);rho=r*sin(theta);figure(1)plot(x,y,'-')N=1000;mcnp_x=zeros(1,N);mcnp_y=zeros(1,N);M=0;for i=1:Nx=2*(rand(1,1)-0.5);y=2*(rand(1,1)-0.5);if((x^2+y^2)<1)M=M+1;mcnp_x(i)=x;mcnp_y(i)=y;endendplot(mcnp_x,mcnp_y,'.')PI1=4*M/N;2、用matlab绘制的图形四、实验结果1.当模拟总计数为1000时,某次计算结果: PI=3.128。
蒙特卡洛(Monte—Carlo)方法求圆周率π

蒙特卡洛(Monte —Carlo )方法求圆周率π蒙特卡罗(Monte Carlo )方法,或称计算机随机模拟方法,是一种基于“随机数”的计算方法。
设X 表示针的中点到最近的一条平行线的距离,Y 表示针与平行线的夹角(如图1所示),如果sin 2X l Y <,或sin 2l X Y <时,针与一条直线相交。
图1蒙特卡洛法求π示意图由于向桌面投针是随机的,所以用来确定针在桌面上位置的(,)X Y 是二维随机向量。
并且X 在0,2a ⎛⎫ ⎪⎝⎭上服从均匀分布,Y 在0,2π⎛⎫ ⎪⎝⎭上服从均匀分布, X 与Y 相互独立。
由此可以写出(,)X Y 的联合概率密度函数:40,02,2()0a x f x y y a ππ⎧<<<=<⎪⎨⎪⎩,,其它于是,所求概率为:sin 2200sin 242sin (,)2l y l x y l l P X Y f x y dxdy dxdy a a πππ<⎧⎫<===⎨⎬⎩⎭⎰⎰⎰⎰ 由于最后的结果与π有关,因此有些人想利用它来计算π的值。
其方法是向桌面投针n 次,若针与直线相交k 次,则针与直线相交的频率为k n ,以频率代替概率,则有2k l n a π=,所以2nl akπ=。
namespace 是指标识符的各种可见范围srand 函数是随机数发生器的初始化函数。
原型:void srand(unsigned seed);用法:它需要提供一个种子,这个种子会对应一个随机数,如果使用相同的种子后面的rand()函数会出现一样的随机数。
如: srand(1); 直接使用1来初始化种子。
不过为了防止随机数每次重复常常使用系统时间来初始化,即使用 time 函数来获得系统时间,它的返回值为从 00:00:00 GMT, January 1, 1970 到现在所持续的秒数,然后将time_t 型数据转化为(unsigned)型再传给srand 函数,即: srand((unsigned) time(&t)); 还有一个经常用法,不需要定义time_t 型t 变量,即: srand((unsigned) time(NULL)); 直接传入一个空指针,因为你的程序中往往并不需要经过参数获得的t 数据。
matlab蒙特卡罗方案积分计算pi值

matlab蒙特卡罗方案积分计算pi值
使用蒙特卡罗方法来计算圆周率$pi$的值,可以按照以下步骤: 1. 在一个正方形内随机生成一组点。
该正方形边长为2,中心坐标为(0,0)。
2. 统计这些点中落在以(0,0)为圆心,半径为1的圆内的点数N。
3. 计算$pi$的估计值:$piapprox4N/M$,其中M为生成的点数。
下面是MATLAB代码实现:
```MATLAB
% 生成M个点
M = 100000;
x = -1 + 2.*rand(M,1);
y = -1 + 2.*rand(M,1);
% 统计落在圆内的点数
N = sum(x.^2 + y.^2 <= 1);
% 计算估计值
pi_estimate = 4*N/M;
% 显示结果
disp(["PI的估计值为 ", num2str(pi_estimate)]);
```
请注意,由于蒙特卡罗方法是一种随机方法,因此计算结果可能会有一定的误差。
如果想要提高精度,需要增加生成的点数M。
实验五 MATLAB蒙特卡罗方法

实验任务一:记录L次实验的实验数据及误差 序号 数据 误差 1 2 3 4 5 6 7
实验任务二:修改实验程序MonteC计算L次实验数 据均值及均值误差( mean 计算平均值 ) L 8 16 32 64 128 256
均值
误差
7/10
冰淇淋锥图形绘制程序
function icecream(m,n) if nargin==0,m=20;n=100;end t=linspace(0,2*pi,n); r=linspace(0,1,m); x=r'*cos(t);y=r'*sin(t); z1=sqrt(x.^2+y.^2); z2=1+sqrt(1+eps-x.^2-y.^2); X=[x;x];Y=[y;y]; Z=[z1;z2]; mesh(X,Y,Z) view(0,-18) colormap([0 0 1]),axis off
xy 2 dxdy 其中D为y= x – 2与y2 = x 所围
D的边界曲线交点为:(–1,1),(4,2),被积函数在求 积区域内的最大值为16。积分值是三维体积,该三维 图形位于立方体区域 0≤ x ≤4,–1≤ y ≤2,0 ≤ z ≤16 内,立方体区域的体积为192。 data=rand(10000,3); x=4*data(:,1); y=-1+3*data(:,2); z=16*data(:,3); II=find(x>=y.^2&x<=y+2&z<=x.*(y.^2)); M=length(II); V=192*M/10000
N个点均匀分布于六面体中,锥体中占有m 个,则锥体与六面体体积之比近似为 m : N
2
用蒙特卡罗方法计算π值实验报告

用蒙特卡罗方法计算π值实验报告蒙特卡罗方法是一种通过随机过程来解决数学、物理和工程问题的数值方法。
在本实验中,我们将利用蒙特卡罗方法计算圆周率π的的值。
以下是实验报告。
1.实验目的本实验的主要目的是利用蒙特卡罗方法计算圆周率π的值,并分析蒙特卡罗方法的可靠性和准确性。
2.实验原理蒙特卡罗方法的基本原理是通过随机采样来估计未知参数的值。
对于圆周率π的计算,我们可以利用正方形和内切圆的关系来实现。
具体步骤如下:(1)在一个给定的单位正方形中,以原点为中心,半径为1的圆。
(2)在正方形中随机生成大量的点,然后计算这些点在圆内的个数。
(3)根据圆的面积与正方形的面积的关系,可以利用这个比例来估计圆周率π的值。
3.实验过程(1)创建一个给定边长的正方形,圆的半径为正方形边长的一半。
(2)随机生成大量坐标点,并计算这些点距离原点的距离。
(3)统计在圆内的点的个数。
(4)根据统计结果计算圆周率π的估计值。
4.实验结果我们进行了多次实验,每次实验生成了100万个点。
然后我们计算每次实验中在圆内的点的个数,并利用这些数据计算圆周率π的估计值。
实验结果如下:实验次数点个数估计π值通过这些实验数据,我们可以计算出平均圆周率π的估计值为3.14085.实验分析通过对多次实验数据的统计分析,我们可以看到蒙特卡罗方法在估计圆周率π的值上具有较高的准确性和可靠性。
实验结果的稳定性较好,不同实验的结果都接近真实值π,而且相对误差较小。
然而,虽然得到的结果接近真实值,但是实验结果的准确性仍然受到概率分布的随机性的限制。
如果我们增加实验次数,可以提高结果的准确性,但是计算的时间也会相应增加。
此外,在计算π的过程中,我们使用了随机生成的数据,因此需要进行大量的计算。
若在实际应用中需要计算更复杂的问题,计算资源和时间消耗将会更大。
6.实验总结本实验使用蒙特卡罗方法计算了圆周率π的估计值。
通过多次实验的数据统计和分析,我们可以得出蒙特卡罗方法在计算π值上的准确性和可靠性较高。
蒙特卡洛方法计算圆周率(C语言实现)

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> int main() { srand(time(0)); double eps = 1e-6, delta; int r = 0, c = 0; int n = 0; double x, y, p1, p2; while (n++ < 100) { x = -1.0 + 2.0 * rand() / RAND_MAX; y = -1.0 + 2.0 * rand() / RAND_MAX; if (x * x + y * y < 1.0) { ++c; 6
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
} else { ++r; } } p1 = 4.0 * c / (c + r); do { x = -1.0 + 2.0 * rand() / RAND_MAX; y = -1.0 + 2.0 * rand() / RAND_MAX; if (x * x + y * y < 1.0) { ++c; } else { ++r; } p2 = 4.0 * c / (c + r); ++n; delta = fabs(p2 - p1); p1 = p2; } while (delta > eps); printf("iterations: %d\n", n - 1); printf("delta: %.7lf\n", delta); printf("value of pi: %lf\n", p2); return 0; } 上述代码首先需要解释的是第 15 行至第 17 行代码,主要作用是先随机生成 100 个点,并以此计算 的圆周率近似值为迭代的初始值,否则将会出现最开始的两次圆周率近似值之差为 0 的情况,导致得不 到正确的计算结果。 第 27 行至第 41 行的循环代码作用在于随着随机点数的逐渐增加,迭代计算连续的两次圆周率近似 值之差,并与阈值进行比较,如果小于该阈值,则退出循环,将最后计算的一次圆周率近似值作为最终 结果。 编译并运行上述程序,得到如下结果: iterations: 859661 delta: 0.0000010 value of pi: 3.140340
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
浙江大学城市学院实验报告课程名称多核与并行程序设计实验项目名称实验五蒙特卡罗法求PI及排序算法学生姓名专业班级学号实验成绩指导老师(签名)日期【实验环境】硬件平台:联想4核,4GZ内存编译器:Microsoft Visual Studio C++ 6.0操作系统:Windows 2003 server sp2测试数据集合:由随机数函数产生的数据集合【实验1】一、问题描述蒙特卡洛算法可理解为通过大量实验,模拟实际行为,来收集统计数据。
本例中,算法随机产生一系列点,模拟这些点落在如下图所示的正方形区域内的情况。
其几何解释如下11图1如图1所示,正方形边长为1,左下顶点与原点重合,两边分别与x,y轴重合。
曲线为1/4圆弧,圆心位于原点,与正方形左下定点重合,半径为1。
正方形面积S1=1,圆弧内面积S2=ππ41412=r。
算法模拟大量点随机落在此正方形区域内,落在圆弧内的点的数量(n2)与点的总数(n1)的比例与面积成正比关系。
即π42121==S S n n (1) 由此可得124n n =π (2)因此,只要计算出落在圆弧内的点的数量在点总数中所占的比例,就能求出π的值。
由图1可知,所有点均落在正方形范围内,因此点的x 坐标满足10≤≤x 。
又,当点落在圆弧范围内,则点的二维坐标关系满足122≤+y x 。
检验每一个点是否满足此关系即可判定改点是否落在圆弧内。
二、串行算法描述本项目中使用了标准C 语言库中的产生随机数函数。
该函数原型为:int rand( void );此函数产生随机数列,每次调用时均返回0到RAND_MAX 之间的一个整数。
void srand( unsigned int seed );此函数为rand ()函数所生成的伪随机数序列设置起始点,使之产生不同的伪随机数。
算法:产生2n 个随机数据,范围[0,1],对每个数据点计算其坐标是否满足122≤+y x ,统计满足此关系的点的数量count ,则 n count4=π三、并行算法3.1 并行算法描述算法步骤:1、确定需要产生的点的个数n ,参与运行的处理器数m ;2、对每一个处理器,生成两个随机数x ,y ,范围[0,1];3、判断两个随机数x ,y 是否满足122≤+y x ;4、若满足,则变量COUNT i++;5、重复步骤2-4,直至每个处理器均生成n/m个随机点;6、收集COUNT i的值,并累加至变量COUNT中,此即为随机点落在圆弧内的数量;7、通过(2)式计算 的值。
3.2 并行算法在Windows下的一个例子#include<stdio.h>#include<windows.h>#include<time.h>//#include <process.h>#include<iostream>#include<fstream>#include<stdlib.h>using namespace std;HANDLE evFinish;long cs=0; //总循环次数long count=0; //主线程有效次数long count_thread=0; //thread线程有效次数time_t start, finish; //定义开始结束时间//thread线程计算量为总数的一半DWORD WINAPI thread(LPVOID param) //这个函数在PDF里WaitForSingleObject(evFinish,INFINITE);//两线程同步count+=count_thread;finish=time(NULL); //记录结束时间printf("并行情况:\n\n");printf("用时=%f 秒\n",difftime(finish,start)); //计算时间差printf("总共的循环次数=%d次\n",cs);printf(" 线程有效次数=%d次\n",count);printf("pi= %f \n",4*(double)count/(double)cs);printf("串行行情况:\n");count=0;start=time(NULL); //记录开始时间for(i=0;i<cs;i++){x=(long double)rand()/(long double)RAND_MAX;y=(long double)rand()/(long double)RAND_MAX;if((x*x+y*y)<=1)count++;// printf("主%d",i);//printf("count%d",count);}finish=time(NULL); //记录结束时间printf("用时=%f 秒\n",difftime(finish,start));printf("总共的循环次数=%d次\n",cs);printf(" 线程有效次数=%d次\n",count);printf("pi= %f \n",4*(double)count/(double)cs);return(0);}四、实验结果1、实验运行结果是多少2、本例中加速比(串行时间/并行时间):S=【实验2】一、问题描述在单核计算环境中,排序算法关注的核心问题是怎样减少要排序数据之间的比较次数或算法所需要的内存空间。
在多核计算环境中,每个核以线程为执行单元,排序程序可以通过生成相互协作的线程来完成排序。
与单核计算环境不同的是,在多核计算环境中更关注数据集的合理划分,更致力于识别可并行执行的任务。
一旦完成这些工作,程序设计上就可以生成对应的线程去执行任务。
理论上,基于相同的串行算法和相同的cache命中率,多核计算速度可以无限接近单核计算速度的P倍,其中P为核的数目。
多核上的并行排序算法所面临的问题在于:1. 未排序的数据集合理划分到每个线程后,最后怎么汇合,形成完整的排好序的数据集呢?2. 怎么保证可并行执行的线程的数目和核的数目相等或稍微多于核的数目,同时也保证这些线程之间的工作量也尽可能的相同呢?在这个实验中,串行的算法采用标准C语言库中的快速排序函数。
并行算法中,先将要处理的数据集均等的分到每个线程中,并使用C语言库中的快速排序函数各自排序。
然后所有线程开始根据相同的数对自己的数据集进行划分,这个数是依据一定的方法选出来的(详见并行算法描述)。
每个线程的数据集都会被分成K份,(其中P<= K < P2 ,P为核的数目),每份将被称为一桶。
很显然这个过程选出了K个数,这些数将被成为bound_value, 记为X1, X2, X3…… X K。
最后每个线程中小于或等于X1的数会被一个独立的线程去归并排序,同样小于或等于X2的数也会被另外一个独立的线程去归并排序,依次类推,直到排好序。
需要指出的是:这个并行版本最消耗时间的部分是一开始每个线程各自的排序,时间为:n n);不过其数据划分和线程生成也相对简单。
最后的归并排序所需时间是线性增O(log长的,即:O(n),因此即使在最后归并部分线程执行的任务已经是不均衡的,也不会对整个程序的性能产生很大的影响。
二、串行算法描述本项目中使用了标准C语言库中的快速排序函数。
该函数原型为:void(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*elem1,const void*elem2));其中base: 待排序数据的数组基址;num: 待排序数据的数目;width: 待排序数据元组的大小;compare: 排序比较函数,当elem1<elem2时返回值小于0,当elem1=elem2时返回值等于0,当elem1>elem2时返回值大于0;三、并行算法3.1 并行算法描述算法:1、将原始待排序的数据分成P等份,每个处理器上对N0个数据进行排序,称每个被排序后的子集为B0,…,Bp-12、Remain_data=N,设定第0组归并起始位置全部为0, i=0,设置第0组在目标数组中的起始位置为03、循环直至remian_data<L( L=N0/P )3.1 选取所有子集中起始位置后续L个元素的最小值bound_value,并获得bound_value的桶号bucket3.2 在所有子集中从起始位置到后续L个元素中选取边界位置,使得边界位置的最后一个元素小于或等于bound_value,而边界位置后的第一元素大于bound_value。
3.3 记录所有的边界位置,并设置所有第i+1组的起始位置为第i组的起始位置加上边界位置3.4 累积所有边界值,得到该归并组的大小3.5 根据归并组大小和本组起始位置计算第i+1组在目标数组中的起始位置。
4、设置最后一个归并组的边界为N05、对所有归并组进行并行P路归并排序。
说明:A.P和多核处理器的数目相同。
比如是双核的,那么P =2;B.Remain_data是每个线程处理的数据集中还没有被X1, X2, X3……划分过的数据集的总数目。
比如,根据X1 每个线程划分出来的数据集为x,y,z……,那么Remain_data=n – x –y –z…..3.2 并行算法在Windows下的一个例子#include <stdlib.h>#include <stdio.h>#include <time.h>#include <search.h>#include<windows.h>#include<process.h>#ifndef _BASIC_SORT_H#define _BASIC_SORT_H#ifndef _SORT_P#define _SORT_Pvoid* sort(void* parameter);void generate_data(int *a,int n);void sort_s(int *a, int n);void view_data(int *a, int n);int check_data_sort(int *a,int n);int compare( const void *arg1, const void *arg2 ); #define MILLION 1000000L#define P 2#define N0 4332539//#define N0 1000000#define N N0*P#define L N0/Pvoid sort_p(int**d, int * b);time_t start, finish; //定义开始结束时间struct merge{ //归并结构int begin[P]; //数组beginint count[P]; //数组countint merge_size; //归并大小int global_pos; //全局位置int merged; //归并是否完成};struct arg_merge_data{ //归并数据结构int **d; //数组的指针struct merge* mp; //归并结构int *b; //整数bint k;//////////////////////////////////////////////// };struct arg_merge_data *tmp2;struct forsort{int *d;int k;};struct forsort forsorta[P];int find_bound_value(int **d,struct merge *mp,int *bucket);int find_min(int **d,struct merge *mp,int *bucket);void find_bound(int **d,struct merge *mp,int bucket,int bound_value);void do_last_merge_block(struct merge *mp);void merge_data(void* arg);void view_merge(int **d,struct merge *mp,int last_merge_block);int start_time();int diff_time();#endif#endifint k; //////////////HANDLE Swait[P];HANDLE Pwait[P];HANDLE pthread[P];HANDLE qthread[P];///////extern int *d[P];///////////////////////////////////////////////////////////////////void generate_data(int *a, int n){ //产生数据int i;for(i=0;i<n;i++){a[i]=rand()%10000; //产生数组a 有n个元素}for(i=0;i<P;i++){d[i]=&(a[i*N0]); //产生数组d 对应a[i]中每个n0块的第i个元素}}////////////////////////////////////////////////////////////////////void sort_s(int *a, int n){ //快排a[i]qsort((void *)a,n,sizeof(int),compare);}////////////////////////////////////////////////////////////////////void* sort( void *parameter){ //快排参数(数组)的前N0个元素struct forsort *forsortb = (struct forsort *)parameter;// printf("\nSetEvent(Swait[%d]) ",forsortb->k);/////////////////===================== int kk=forsortb->k;qsort(/*(void*)*/forsortb->d, N0, sizeof(int), compare);SetEvent(Swait[kk]);//printf("\n%d",kk);return (void*)0;}///////////////////////////////////////////////////////////////////void view_data(int *a, int n){int i=n,j;int index=0;while(i>N0){for(j=0;j<N0;j++){printf("%d\t",a[index++]); //输出a[i]中前N0个数}printf("\n");i-=N0;}for(;i>0;i--){ //输出a[i]中N0后面的个数printf("%d\t",a[index++]);}printf("\n");}//////////////////////////////////////////////////////////////////////int check_data_sort(int *a,int n){ //找出不服和大小顺序的位置int i;for(i=0;i<n-1;i++){if(a[i]>a[i+1]) break;}return i;}//////////////////////////////////////////////////////////////////////int compare( const void *arg1, const void *arg2 ){ //返回arg1与arg2的差int a=*(int *)arg1,b=*(int *)arg2;return a-b;}////////////////////////////////////////////////////////////////////int a[N];//data for parallel sortint b[N];// the result of parallel sortint *d[P];// for parallel sortint s[N];//data for serial sortstruct merge m_list[P*P];//record of partitionint merge_block; // the number of partitionDWORD thr_id[P*P];long timedif;// for estimate the exection time//struct timeval end; // ...//struct timeval start;// ...void inite(){int i;//forsorta=(struct forsort *) calloc(P, sizeof (struct forsort));for(i=0;i<P;i++){Swait[i]=CreateEvent(NULL,FALSE,FALSE,NULL);Pwait[i]=CreateEvent(NULL,FALSE,FALSE,NULL);/* for(int j=0;j<P;j++){forsorta[i].d[j]=d[j];// printf("forsorta[%d].d[%d]=%d\n",i,j,forsorta[i].d[j]);}*/}}void main() //在PDF里调用/////////////////////////////////////////////////////////////////////////////////四、实验结果1、测试数据集合:由随机数函数产生的数据集合总共有个数2、实验结果是:3、本例中加速比(串行时间/并行时间):S=。