并行计算大作业之多边形相交(OpenMP、MPI、Java、Windows)

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

吐槽:

话说,相当郁闷,2015年,第一次打开博客,准备总结一下这一年。。

结果博客被封了= =!

今天,终于解封了,换了密码,换了密保....

但是,写回顾的激情有点退散了。。

明后两天要上课,明天还要验收一个综合设计大作业,再后两天要考试,再后两天继续上课,然后才能放假。。。

回顾,就等着考完试再写吧,正好趁这几天好好总结一下。

正文:

这是这学期开的 《并行计算与程序设计》,学了一些并行计算的东东。

期末没有考试,就是选择一个算法,用 OpenMP、MPI、Java、Windows 实现,当然还有额外的,比如 Hadoop、GPU、Linux等(这些没有花时间去研究。。)

我选择的算法就是很简单的,多边形相交问题,只是用到了并行计算的一些基础。

发一篇博客,把这个大作业记录下来~。~

1. 功能描述与解决方案

1.1 功能描述:

在很多实际应用中,要求确定一组几何物体(目标)是否相交。例如,在模式分类中,必须确定代表不同类别的空间中的不同区域是否具有共同的子区域;在集成电路设计中,重要的是要避免导线的交叉和元件的重叠;在计算机图形学中,要求消去三维景象的二维表示中的隐线和隐面等等。像如上的这些问题都可归结为物体的相交问题(Intersection Problem)。

设有平面上的两个多边形(允许有边相交)R和Q,如果多边形R的一条边和Q的一条边相交,则称R和Q是相交的。所以两个多边形的相交问题可以转化为线段与多边形的相交问题。三维空间的相交问题与二维平面上的相交问题并没有实质的区别,只是在判断边的相交时比二维问题上判断边的相交要麻烦,因为三维空间上的点坐标是与3个值有关的。

下面描述的算法都是针对二维平面上的多边形相交而言的。

1.2 解决方案

最基本的相交问题是判断两条线段是否相交。而边与多边形相交就是判断一条边和多条边中的某条边是否相交的算法。要是一个多边形的某条边与另一个多边形的一条边相交,则就称两个多边形相交。这样两个多边形相交的问题就转化为多条边与一个多边形相交的问题。

2. 算法设计

2.1 串行算法设计

输入:多边形R的n条边E1,E2,,…,En的两个端点坐标集合S1,多边形Q的m条边

F1,F2,,…,Fm的两个端点坐标集合S2,要求集合内点的顺序为顺时针方向。

输出:两个多边形是否相交:true(两多边形相交);false(两多边形不相交)

Begin
    for i=1 to n do
        for j=1 to m do
            if (Ei intersects Fj ) then
                return true
            end if
        end for
    end for
    return false
End

显然上述算法所需时间为O(mn)。

2.2 并行算法设计

输入:多边形R的n条边E1,E2,,…,En的两个端点坐标集合S1,多边形Q的m条边

F1,F2,,…,Fm的两个端点坐标集合S2,要求集合内点的顺序为顺时针方向。

输出:两个多边形是否相交:true(两多边形相交);false(两多边形不相交)

Begin
    for i=1 to n par-do
        for j=1 to m
            if (Ei intersects Fj ) then
                return true
            end if
        end for
    end for
    return false;
End

3.各种并行算法

3.1 OpenMP 方法

#include "stdafx.h"
#include "omp.h"
#include <time.h>
#include <windows.h>

// 设置相交精度与多边形点个数的上限
const double EPS = 1e-10;
const int MAX = 100001;

struct point
{
    double x,y;
}lx_R[MAX],lx_Q[MAX];
// 多边形R与Q的点个数
int lx_n,lx_m;
// 定义相应比较函数
double Max(double a,double b)   {return a>b?a:b;}
double Min(double a,double b)   {return a>b?b:a;}  

// 判断两线段是否相交
bool lx_inter(point p1,point p2,point p3,point p4)
{
    if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
       Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
       Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
       Min(p3.y,p4.y)>Max(p1.y,p2.y) )
        return 0;
    double k1,k2,k3,k4;
    k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
    k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
    k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
    k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
    return (k1*k2<=EPS && k3*k4<=EPS);
}  

// 获取点的坐标函数
void lx_getPoint(char lx_c )
{
	int i;
	printf("please input the number of polygon %c: ",lx_c);

	if( lx_c == 'R' )
	{
		scanf("%d",&lx_n);
		printf("\nplease input all point position: \n");
		for( i = 0 ; i < lx_n ; ++i )
			scanf("%lf %lf",&lx_R[i].x,&lx_R[i].y);
	}
	else
	{
		scanf("%d",&lx_m);
		printf("\nplease input all point position: \n");
		for( i = 0 ; i < lx_m ; ++i )
			scanf("%lf %lf",&lx_Q[i].x,&lx_Q[i].y);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	clock_t t1,t2;
	int i,j;
	bool isCross=false;
	// 获取多边形的点
	lx_getPoint('R');
	lx_getPoint('Q');

	t1=clock();
	omp_set_num_threads(2);

	// k 用来控制循环次数
	for( int k = 0 ; k < 10001 ; ++k )
	{
#pragma omp parallel for
	for( i = 0 ; i < lx_n ; ++i )
		for( j = 0 ; j < lx_m ; ++j )
			if( lx_inter( lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m] ) )
				isCross=true;
	}

	if( isCross )	printf("多边形相交!\n");
	else	printf("多边形不相交!\n");

	t2=clock();

	printf("Time is %d\n",t2-t1);

	system("pause");
	return 0;
}

3.2 MPI 方法

#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <windows.h>

// 设置相交精度 与 多边形点个数的上限
const double EPS = 1e-10;
const int MAX = 100001;

struct point
{
    double x,y;
}lx_R[MAX],lx_Q[MAX];
// 多边形R与Q的点个数
int lx_n,lx_m;
// 定义相应比较函数
double Max(double a,double b)   {return a>b?a:b;}
double Min(double a,double b)   {return a>b?b:a;}  

// 判断两线段是否相交
bool lx_inter(point p1,point p2,point p3,point p4)
{
    if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
       Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
       Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
       Min(p3.y,p4.y)>Max(p1.y,p2.y) )
        return 0;
    double k1,k2,k3,k4;
    k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
    k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
    k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
    k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
    return (k1*k2<=EPS && k3*k4<=EPS);
}  

// 获取点的坐标函数
void lx_getPoint( void )
{
	lx_n=76;
	lx_m=76;
	int i;
	for( i = 0 ; i < 20 ; ++i )	{
		lx_R[i].x=1;
		lx_R[i].y=i+1;
		lx_Q[i].x=1;
		lx_Q[i].y=i+1;
	}
	for( i = 19 ; i < 39 ; ++i )	{
		lx_R[i].x=i-18;
		lx_R[i].y=20;
		lx_Q[i].x=i-18;
		lx_Q[i].y=20;
	}
	for( i = 38 ; i < 58 ; ++i )	{
		lx_R[i].x=20;
		lx_R[i].y=58-i;
		lx_Q[i].x=20;
		lx_Q[i].y=58-i;
	}
	for( i = 57 ; i < 76 ; ++i )	{
		lx_R[i].x=77-i;
		lx_R[i].y=1;
		lx_Q[i].x=77-i;
		lx_Q[i].y=1;
	}

}

int main( int argc , char *argv[] )
{
	MPI_Comm comm = MPI_COMM_WORLD;
	int rank ,size,i,j,ans;
	int rslt,myrslt,loop;
	double lx_t1,lx_t2;
	char processor_name[MPI_MAX_PROCESSOR_NAME];
	int namelen;

	MPI_Init(&argc,&argv);
	MPI_Comm_rank(MPI_COMM_WORLD,&rank);
	MPI_Comm_size(MPI_COMM_WORLD,&size);
	MPI_Get_processor_name(processor_name,&namelen);

	if( rank == 0 )	{
		// 获取点坐标集合
		lx_getPoint();

		lx_t1=MPI_Wtime();
	}

	loop = 0;
	while( loop < 100 )
	{

		// 广播两个多边形的点集合
		MPI_Bcast(&lx_n,1,MPI_INT,0,MPI_COMM_WORLD);
		MPI_Bcast(&lx_m,1,MPI_INT,0,MPI_COMM_WORLD);

		for( i = 0 ; i < lx_n ;++i )		{
			MPI_Bcast(&lx_R[i].x,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
			MPI_Bcast(&lx_R[i].y,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
		}
		for( j= 0 ; j < lx_m ;++j)	{
			MPI_Bcast(&lx_Q[j].x,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
			MPI_Bcast(&lx_Q[j].y,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
		}

		rslt = 0;
		for( i = rank ; i<lx_n ; i+=size )	{
			for( j = 0; j < lx_m ; ++j )	{
				if( lx_inter( lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m] ) )
					rslt= 1;
			}
		}
		myrslt = rslt;
		MPI_Reduce(&myrslt,&ans,1,MPI_INT,MPI_SUM,0,comm);

		++loop;
	}
	if( rank == 0 )	{
		if( ans > 0 )	printf("两多边形相交!\n");
		else	printf("两多边形不相交!\n");
		lx_t2=MPI_Wtime();
		printf("时间为 %lf \n ",lx_t2-lx_t1);
	}

	MPI_Finalize();
	system("pause");
	return 0;
}

3.3 Java 方法

3.3.1 Java Thread 方法

package lx_polygonCrossing_javaThread;

public class lx_polygonCrossingThread extends Thread {

	private int start,end,lx_n,lx_m;
	private boolean isCross = false;

	private double EPS = 1e-10;
	public lx_Point[] lx_R = new lx_Point[100001];
	public lx_Point[] lx_Q = new lx_Point[100001];

	public double Max( double x , double y )	{
		return x>y?x:y;
	}
	public double Min( double x , double y )	{
		return x<y?x:y;
	}

	public	boolean lx_inter(lx_Point p1,lx_Point p2,lx_Point p3,lx_Point p4)
	{
	    if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
	       Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
	       Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
	       Min(p3.y,p4.y)>Max(p1.y,p2.y) )
	        return false;
	    double k1,k2,k3,k4;
	    k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
	    k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
	    k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
	    k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
	    return (k1*k2<=EPS && k3*k4<=EPS);
	}  

	public void lx_getPoint( )
	{
		for( int k = 0 ; k < 100001 ; ++k )
			lx_R[k] = new lx_Point();
		for( int k = 0 ;k < 100001 ; ++k )
			lx_Q[k] = new lx_Point();

		int i,j=0;
		for( i = 1 ;i <= 7600 ; ++i,++j )	{
			lx_R[j].x=1;
			lx_R[j].y=i;
			lx_Q[j].x=1;
			lx_Q[j].y=i;
		}
		for( i = 2 ; i <= 7600 ; ++i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=7600;
			lx_Q[j].x=i;
			lx_Q[j].y=7600;
		}
		for( i = 7599 ; i > 0 ; --i,++j )	{
			lx_R[j].x=7600;
			lx_R[j].y=i;
			lx_Q[j].x=7600;
			lx_Q[j].y=i;
		}
		for( i = 7599 ; i > 0 ; --i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=1;
			lx_Q[j].x=i;
			lx_Q[j].y=1;
		}

	}

	public lx_polygonCrossingThread(int start,int end,int lx_n,int lx_m)	{
		super();
		this.start=start;
		this.end=end;
		this.lx_n=lx_n;
		this.lx_m=lx_m;
	}

	public void run()	{
		for( int i = start ; i < end ; ++i )
			for( int j = 0 ; j < lx_m ; ++j )
				if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
					isCross = true;
	}

	public boolean getIscross( )	{
		return isCross;
	}

	public void runS()	{
		for( int i = 0 ; i < lx_n ; ++i )
			for( int j = 0 ; j < lx_m ; ++j )
				if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
					isCross = true;
	}

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub

		lx_polygonCrossingThread thread1 = new lx_polygonCrossingThread(0,30396/2,30396,30396);
		lx_polygonCrossingThread thread2 = new lx_polygonCrossingThread(30396/2,30396,30396,30396);
		thread1.lx_getPoint();
		thread2.lx_getPoint();

		long startTime = System.currentTimeMillis();
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();
		long endTime = System.currentTimeMillis();

		if( thread1.getIscross() || thread2.getIscross() )
			System.out.println("两多边形相交!");
		else
			System.out.println("两多边形不相交!");
		System.out.println("并行时间="+(endTime-startTime));

		startTime=System.currentTimeMillis();
		lx_polygonCrossingThread serial = new lx_polygonCrossingThread(0,30396/2,30396,30396);
		serial.lx_getPoint();
		serial.runS();
		endTime=System.currentTimeMillis();
		if( serial.getIscross() )
			System.out.println("两多边形相交!");
		else
			System.out.println("两多边形不相交!");
		System.out.println("串行时间="+(endTime-startTime));
	}

}

3.3.2 Java Runnable 方法

package lx_polygonCrossing_javaRunnable;

public class lx_polygonCrossingRunnable {

	public static void main(String[] args) throws InterruptedException {
		work work1 = new work(0,30396/2,30396,30396);
		work work2 = new work(30396/2,30396,30396,30396);
		work1.lx_getPoint();
		work2.lx_getPoint();
		Thread thread1 = new Thread(work1);
		Thread thread2 = new Thread(work2);
		long startTime = System.currentTimeMillis();
		thread1.start();
		thread2.start();
		thread1.join();
		thread2.join();
		long endTime = System.currentTimeMillis();
		if( work1.getIscross() || work2.getIscross() )
			System.out.println("两多边形相交!");
		else
			System.out.println("两多边形不相交!");
		System.out.println("并行时间="+(endTime-startTime));

		startTime = System.currentTimeMillis();
		work work = new work(0,30396/2,30396,30396);
		work.lx_getPoint();
		boolean isC = work.runS();
		endTime = System.currentTimeMillis();
		if( isC )
			System.out.println("两多边形相交!");
		else
			System.out.println("两多边形不相交!");
		System.out.println("串行时间="+(endTime-startTime));

	}

}

class work implements Runnable {
	private int start,end,lx_n,lx_m;
	private boolean isCross = false;

	private double EPS = 1e-10;
	public lx_Point[] lx_R = new lx_Point[100001];
	public lx_Point[] lx_Q = new lx_Point[100001];

	public double Max( double x , double y )	{
		return x>y?x:y;
	}
	public double Min( double x , double y )	{
		return x<y?x:y;
	}

	public	boolean lx_inter(lx_Point p1,lx_Point p2,lx_Point p3,lx_Point p4)
	{
	    if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
	       Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
	       Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
	       Min(p3.y,p4.y)>Max(p1.y,p2.y) )
	        return false;
	    double k1,k2,k3,k4;
	    k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
	    k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
	    k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
	    k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
	    return (k1*k2<=EPS && k3*k4<=EPS);
	}  

	public void lx_getPoint( )
	{
		for( int k = 0 ; k < 100001 ; ++k )
			lx_R[k] = new lx_Point();
		for( int k = 0 ;k < 100001 ; ++k )
			lx_Q[k] = new lx_Point();

		int i,j=0;
		for( i = 1 ;i <= 7600 ; ++i,++j )	{
			lx_R[j].x=1;
			lx_R[j].y=i;
			lx_Q[j].x=1;
			lx_Q[j].y=i;
		}
		for( i = 2 ; i <= 7600 ; ++i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=7600;
			lx_Q[j].x=i;
			lx_Q[j].y=7600;
		}
		for( i = 7599 ; i > 0 ; --i,++j )	{
			lx_R[j].x=7600;
			lx_R[j].y=i;
			lx_Q[j].x=7600;
			lx_Q[j].y=i;
		}
		for( i = 7599 ; i > 0 ; --i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=1;
			lx_Q[j].x=i;
			lx_Q[j].y=1;
		}

	}

	public work(int start,int end,int lx_n,int lx_m)	{
		super();
		this.start=start;
		this.end=end;
		this.lx_n=lx_n;
		this.lx_m=lx_m;
	}

	public void run()	{
		for( int i = start ; i < end ; ++i )
			for( int j = 0 ; j < lx_m ; ++j )
				if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
					isCross = true;
	}

	public boolean getIscross( )	{
		return isCross;
	}

	public boolean runS()	{
		boolean isC=false;
		for( int i = 0 ; i < lx_n ; ++i )
			for( int j = 0 ; j < lx_m ; ++j )
				if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
					isC = true;
		return isC;
	}
}

3.4 Windows 方法

3.4.1 win32 方法

#include "stdafx.h"
#include <Windows.h>
#include "time.h"

const double EPS = 1e-10;
struct lx_Point
{
	double x,y;
}lx_R[40000],lx_Q[40000];

HANDLE finish[2];
HANDLE finish2;
int lx_n,lx_m;
bool isCross[2];

double Max( double x , double y )	{
	return x>y?x:y;
}
double Min( double x , double y )	{
	return x<y?x:y;
}

bool lx_inter(lx_Point p1,lx_Point p2,lx_Point p3,lx_Point p4)
{
	if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
		Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
		Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
		Min(p3.y,p4.y)>Max(p1.y,p2.y) )
		return false;
	double k1,k2,k3,k4;
	k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
	k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
	k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
	k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
	return (k1*k2<=EPS && k3*k4<=EPS);
}  

void lx_getPoint( )
{
	lx_n=3036;
	lx_m=3036;
	int i,j=0;
		for( i = 1 ;i <= 760 ; ++i,++j )	{
			lx_R[j].x=1;
			lx_R[j].y=i;
			lx_Q[j].x=1;
			lx_Q[j].y=i;
		}
		for( i = 2 ; i <= 760 ; ++i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=760;
			lx_Q[j].x=i;
			lx_Q[j].y=760;
		}
		for( i = 759 ; i > 0 ; --i,++j )	{
			lx_R[j].x=760;
			lx_R[j].y=i;
			lx_Q[j].x=760;
			lx_Q[j].y=i;
		}
		for( i = 759 ; i > 0 ; --i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=1;
			lx_Q[j].x=i;
			lx_Q[j].y=1;
		}

}

DWORD WINAPI ThreadOne(LPVOID param)		{
	for( int i = 0 ; i < lx_n/2 ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCross[0] = true;
	SetEvent( finish[0] );
	return 0;
}

DWORD WINAPI ThreadTwo(LPVOID param)	{
	for( int i = lx_n/2 ; i < lx_n ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCross[1] = true;
	SetEvent( finish[1] );
	return 0;
}

DWORD WINAPI ThreadThree(LPVOID param)		{
	bool isCrossS=false;
	for( int i = 0 ; i < lx_n ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCrossS = true;
	if( isCrossS )	printf("两多边形相交!\n");
	else	printf("两多边形不相交!\n");

	SetEvent(finish2);
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	lx_getPoint();

	clock_t start=clock();
	finish[0] = CreateEvent(NULL,false,false,NULL);
	finish[1] = CreateEvent(NULL,false,false,NULL);
	HANDLE thread1 = CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
	HANDLE thread2 = CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
	WaitForMultipleObjects(2,finish,true,INFINITE);
	clock_t end = clock();
	if( isCross[0] || isCross[1] )
		printf("两多边形相交!\n");
	else
		printf("两多边形不相交!\n");
	printf("andtime=%d\n",end-start);

	clock_t start2 = clock();
	finish2 = CreateEvent(NULL,false,false,NULL);
	HANDLE thread3 = CreateThread(NULL,0,ThreadThree,NULL,0,NULL);
	WaitForSingleObject(finish2,INFINITE);
	clock_t end2 = clock();
	printf("serialtime=%d\n",end2-start2);

	system("pause");
	return 0;
}

3.4.2 MFC 方法

#include "stdafx.h"
#include <afxmt.h>
#include <afxwin.h>

const double EPS = 1e-10;
struct lx_Point
{
	double x,y;
}lx_R[80000],lx_Q[80000];
bool isCross[2];
int lx_n,lx_m;

CEvent faxEvent(false);
CEvent faxEvent1(false);
CEvent faxEvent2(false);
CSemaphore g_clsSemaphore(2,2);

double Max( double x , double y )	{
	return x>y?x:y;
}
double Min( double x , double y )	{
	return x<y?x:y;
}

bool lx_inter(lx_Point p1,lx_Point p2,lx_Point p3,lx_Point p4)
{
	if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
		Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
		Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
		Min(p3.y,p4.y)>Max(p1.y,p2.y) )
		return false;
	double k1,k2,k3,k4;
	k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
	k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
	k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
	k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
	return (k1*k2<=EPS && k3*k4<=EPS);
}  

void lx_getPoint( )
{
	lx_n=3036;
	lx_m=3036;
	int i,j=0;
		for( i = 1 ;i <= 760 ; ++i,++j )	{
			lx_R[j].x=1;
			lx_R[j].y=i;
			lx_Q[j].x=1;
			lx_Q[j].y=i;
		}
		for( i = 2 ; i <= 760 ; ++i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=760;
			lx_Q[j].x=i;
			lx_Q[j].y=760;
		}
		for( i = 759 ; i > 0 ; --i,++j )	{
			lx_R[j].x=760;
			lx_R[j].y=i;
			lx_Q[j].x=760;
			lx_Q[j].y=i;
		}
		for( i = 759 ; i > 0 ; --i,++j )	{
			lx_R[j].x=i;
			lx_R[j].y=1;
			lx_Q[j].x=i;
			lx_Q[j].y=1;
		}
}

UINT ThreadProc4( LPVOID pParam)	{
	g_clsSemaphore.Lock();
	for( int i = 0 ; i < lx_n/2 ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCross[0] = true;
	SetEvent(faxEvent1);
	return 0;
}

UINT ThreadProc5( LPVOID pParam)	{
	g_clsSemaphore.Lock();
	for( int i = lx_n/2 ; i < lx_n ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCross[1] = true;
	g_clsSemaphore.Unlock();
	SetEvent(faxEvent2);
	return 0;
}

UINT ThreadProc6( LPVOID pParam )	{
	g_clsSemaphore.Lock();
	bool isCrossS=false;
	for( int i = 0 ; i < lx_n ; ++i )
		for( int j = 0 ; j < lx_m ; ++j )
			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
				isCrossS = true;
	g_clsSemaphore.Unlock();
	if( isCrossS )	printf("两多边形相交!\n");
	else	printf("两多边形不相交!\n");
	SetEvent(faxEvent);
	return 0;
}

int _tmain( int argc, _TCHAR* argv[] )	{

	lx_getPoint();

	clock_t start = clock();
	AfxBeginThread(ThreadProc4,NULL);
	AfxBeginThread(ThreadProc5,NULL);
	WaitForSingleObject(faxEvent1,INFINITE);
	WaitForSingleObject(faxEvent2,INFINITE);

	if( isCross[0] || isCross[1] )
		printf("两多边形相交!\n");
	else
		printf("两多边形不相交!\n");

	clock_t end = clock();
	printf("andtime = %d \n",end-start);

	clock_t start2 = clock();
	AfxBeginThread(ThreadProc6,NULL);
	WaitForSingleObject(faxEvent,INFINITE);
	clock_t end2 = clock();
	printf("serialtime = %d \n ",end2-start2);

	system("pause");
	return 0;
}

3.4.3 .Net 方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;

namespace lx_polygonCrossingNet
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            Work work1 = new Work(0, 3036 / 2, 3036, 3036);
            ThreadStart thread1 = new ThreadStart( work1.run );
            Thread newthread1 = new Thread(thread1);
            Work work2 = new Work(3036 / 2, 3036, 3036, 3036);
            ThreadStart thread2 = new ThreadStart( work2.run );
            Thread newthread2 = new Thread(thread2);

            work1.lx_getPoint();
            work2.lx_getPoint();

            stopwatch.Start();
            newthread1.Start();
            newthread2.Start();
            newthread1.Join();
            newthread2.Join();
            stopwatch.Stop();

            TimeSpan timeSpan = stopwatch.Elapsed;
            double milliseconds = timeSpan.TotalMilliseconds;
            if( work1.getIscross() || work2.getIscross() )
			    Console.WriteLine("两多边形相交!");
		    else
                Console.WriteLine("两多边形不相交!");
            Console.Write("parallel time = ");
            Console.WriteLine(milliseconds);

            Work work = new Work(0, 3036, 3036, 3036);
            work.lx_getPoint();
            stopwatch.Start();

            if ( work.runS() )
                Console.WriteLine("两多边形相交!");
            else
                Console.WriteLine("两多边形不相交!");
            stopwatch.Stop();
            TimeSpan timeSpan2=stopwatch.Elapsed;
            double milliseconds2 = timeSpan2.TotalMilliseconds;
            Console.Write("serial time=");
            Console.WriteLine(milliseconds2);
            Console.Read();
        }
    }

    class lx_Point
    {
        public double x;
        public double y;
        public lx_Point()
        {
            this.x = 0;
            this.y = 0;
        }
    }

    class Work
    {
        private int start,end,lx_n,lx_m;
	    private bool isCross = false;

    	private double EPS = 1e-10;
    	public lx_Point[] lx_R = new lx_Point[100001];
    	public lx_Point[] lx_Q = new lx_Point[100001];

    	public double Max( double x , double y )	{
    		return x>y?x:y;
    	}
    	public double Min( double x , double y )	{
    		return x<y?x:y;
    	}

        public bool lx_inter(lx_Point p1, lx_Point p2, lx_Point p3, lx_Point p4)
    	{
	        if( Min(p1.x,p2.x)>Max(p3.x,p4.x) ||
	            Min(p1.y,p2.y)>Max(p3.y,p4.y) ||
	            Min(p3.x,p4.x)>Max(p1.x,p2.x) ||
	            Min(p3.y,p4.y)>Max(p1.y,p2.y) )
	                return false;
            double k1,k2,k3,k4;
	        k1 = (p2.x-p1.x)*(p3.y-p1.y) - (p2.y-p1.y)*(p3.x-p1.x);
	        k2 = (p2.x-p1.x)*(p4.y-p1.y) - (p2.y-p1.y)*(p4.x-p1.x);
	        k3 = (p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x);
	        k4 = (p4.x-p3.x)*(p2.y-p3.y) - (p4.y-p3.y)*(p2.x-p3.x);
	        return (k1*k2<=EPS && k3*k4<=EPS);
	    }  

	    public void lx_getPoint( )
    	{
    		for( int k = 0 ; k < 100001 ; ++k )
    			lx_R[k] = new lx_Point();
    		for( int k = 0 ;k < 100001 ; ++k )
    			lx_Q[k] = new lx_Point();

            int i, j = 0;
            for (i = 1; i <= 760; ++i, ++j)
            {
                lx_R[j].x = 1;
                lx_R[j].y = i;
                lx_Q[j].x = 1;
                lx_Q[j].y = i;
            }
            for (i = 2; i <= 760; ++i, ++j)
            {
                lx_R[j].x = i;
                lx_R[j].y = 760;
                lx_Q[j].x = i;
                lx_Q[j].y = 760;
            }
            for (i = 759; i > 0; --i, ++j)
            {
                lx_R[j].x = 760;
                lx_R[j].y = i;
                lx_Q[j].x = 760;
                lx_Q[j].y = i;
            }
            for (i = 759; i > 0; --i, ++j)
            {
                lx_R[j].x = i;
                lx_R[j].y = 1;
                lx_Q[j].x = i;
                lx_Q[j].y = 1;
            }

    	}

	    public Work(int start,int end,int lx_n,int lx_m)	{
	    	this.start=start;
	    	this.end=end;
	    	this.lx_n=lx_n;
	    	this.lx_m=lx_m;
	    }

    	public void run()	{
	    	for( int i = start ; i < end ; ++i )
		    	for( int j = 0 ; j < lx_m ; ++j )
	    			if( lx_inter(lx_R[i] , lx_R[(i+1)%lx_n] , lx_Q[j] , lx_Q[(j+1)%lx_m]) )
	    				isCross = true;
    	}

        public bool getIscross()
        {
            return isCross;
        }

        public bool runS()
        {
            bool isC = false;
            for (int i = 0; i < lx_n; ++i)
                for (int j = 0; j < lx_m; ++j)
                    if (lx_inter(lx_R[i], lx_R[(i + 1) % lx_n], lx_Q[j], lx_Q[(j + 1) % lx_m]))
                        isC = true;
            return isC;
        }
    }
}

话说,把这些弄出来,感觉挺不错的,就是测试数据很不好弄。

其他人有弄排序的,随机出来数据就行了,我这个对输入有要求,无法随机输入。

好纠结的说,而且正常来说可以提前跳出(判断出来任何一段线段相交即可),也无法准确测量时间。

所以就特别固定了数据,也不允许提前跳出了。

并行计算,还是挺好玩的,有些遗憾,没弄Hadoop那些了。。

***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************

时间: 2024-12-26 19:39:48

并行计算大作业之多边形相交(OpenMP、MPI、Java、Windows)的相关文章

代写大作业、代写大学计算机基础编程

代写大作业.代写大学计算机基础编程<大学计算机基础>常规班大作业题目 要求:从下列题目中,选择1道题目作为大作业,实现程序并撰写实验报告:文科学生可以选做任何题目,理科学生不可以选做"文科题目". 作业一 信息录入与查找系统 设计一个信息录入与查找系统,使其具有基本身份信息的录入功能,并能在录入的数据中根据一个或多个查找关键字查询出所有符合条件的人.具体要求如下: 1. 设计一个 GUI 界面,其中具有多个输入框,对应姓名.性别.年龄.血型.星座.身高.体重等数据:并有确定

《Java语言程序设计》大作业报告 九宫格游戏

    <Java语言程序设计>大作业报告     中国石油大学(北京)2015 - 2016 学年第二学期     班级:_____计算机14-1_______ 姓名:_____  许 恺_________________ 学号:______2014011329___________     题意分析 程序首先需要九个可以移动的格子,大小相等,有字符串标示,其次要可以相应鼠标和键盘方向键的控制,可以自由移动,并且与此同时记录步数,最后在满足条件时弹出对话框并显示步数以及是否打破记录,关于打破

数据库大作业--由python+flask

这个是项目一来是数据库大作业,另一方面也算是再对falsk和python熟悉下,好久不用会忘很快. 界面相比上一个项目好看很多,不过因为时间紧加上只有我一个人写,所以有很多地方逻辑写的比较繁琐,如果是想学习flask还是推荐之前的项目,地址:http://www.cnblogs.com/INnoVationv2/p/5837495.html 寒假回去我会重构下代码,然后再po出来. 不知道怎么做数据库大作业的也可以参考: 所有功能: 三类用户模式: 一.管理员 1.查看所有档案 2.修改档案信息

机电传动控制大作业第一阶段

机电传动控制大作业第一阶段 一.系统硬件接口定义 系统硬件可分为显示部分.按键输入部分和运动控制部分. 显示部分包括每个楼层的电梯外的楼层显示LED和上下楼指示箭头.电梯内的楼层显示LED和上下楼箭头,LED显示如果用七段共阴数码管则每个LED需要七个继电器来控制显示字符,上下楼箭头每个需要两个继电器IO进行控制,而控制它们的信号源则来自每层楼的行程开关,共七个开关进行输入. 按键输入部分为电梯内和楼层中,电梯内七个常开触点输入楼层,两个常开触点控制开关门,同时需要点亮楼层按键上的指示灯,则需要

DIP大作业---图像分割

数字图像处理课程的大作业,要求如下: 图像分割就是把图像分成若干个特定的.具有独特性质的区域并提出感兴趣目标的技术和过程.它是由图像处理到图像分析的关键步骤.现有的图像分割方法主要分以下几类:基于阈值的分割方法.基于区域的分割方法.基于边缘的分割方法以及基于特定理论的分割方法等.图像分割后提取出的目标可以用于图像语义识别,图像搜索等等领域.要求1:输入一副真彩色RGB图像dog.jpg,完成对小狗的分割,输入结果为只包含小狗区域的二值图(matlab环境下,小狗区域值为1,其他区域值为0).要求

Smith-waterman算法 openmp+mpi实现

//此Smith-Waterman 算法分别用mpi与openmp实现是没问题的,但是两个混合编程的时候就会出各种问题,希望懂的能够给指条明路...万分感谢 #include <omp.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <mpi.h> /*Fil

不是所有的大作业都叫微信抢票大作业

为时四周的微信抢票大作业终于接近尾声,回首这段时间,真是感慨万千.不是所有的大作业都是微信抢票大作业,能够让人同时体验产品经理.开发工程师.测试工程师.运维工程师四个角色.经过了微信抢票大作业的洗礼,才知道之前对老师上课讲的内容只是一知半解,只有实践才能出真知. 一.搞开发 讲道理,这次大作业的开发工作其实不是很多.因为框架设计的很好,接口也介绍的很详细,只需要按部就班填坑就可以达到基本要求了. 但是既然助教上课都提到了几个优化方案,比如内存型数据库,异步队列等,好奇如我怎能不试呢.于是就开始给

机电传动控制大作业 第一阶段

机电传动控制大作业 第一阶段 一.系统硬件接口定义 1.电梯内操作界面: 标有1-7数字的按钮(每个按钮有一个LED灯,按下按钮灯即亮),开门,关门以及紧急报警的按钮和楼层指示的LED数码管.电梯门的打开和关闭需要两个行程开关,接收到开关门的信息可以直接控制门的开关. 2.楼栋操作界面: 2-6层有上行和下行按钮,1层只有上行,7层只有下行.每个按钮都连接一个LED灯(按下按钮灯即亮).两个LED数码管显示所在的楼层. 3.动力相关硬件: 每部电梯配有一台交流异步变频电机和变频器,电机接口接电机

Inheritance - SGU 129(线段与多边形相交的长度)

题目大意:给一个凸多边形(点不是按顺序给的),然后计算给出的线段在这个凸多边形里面的长度,如果在边界不计算. 分析:WA2..WA3...WA4..WA11...WA的无话可说,总之细节一定考虑清楚,重合的时候一定是0 代码如下: ========================================================================================================= #include<stdio.h> #include&