首页 > 代码库 > 并行计算大作业之多边形相交(OpenMP、MPI、Java、Windows)

并行计算大作业之多边形相交(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********************************************

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