并行计算八皇后问题.docx

上传人:b****4 文档编号:24262588 上传时间:2023-05-25 格式:DOCX 页数:47 大小:1.91MB
下载 相关 举报
并行计算八皇后问题.docx_第1页
第1页 / 共47页
并行计算八皇后问题.docx_第2页
第2页 / 共47页
并行计算八皇后问题.docx_第3页
第3页 / 共47页
并行计算八皇后问题.docx_第4页
第4页 / 共47页
并行计算八皇后问题.docx_第5页
第5页 / 共47页
点击查看更多>>
下载资源
资源描述

并行计算八皇后问题.docx

《并行计算八皇后问题.docx》由会员分享,可在线阅读,更多相关《并行计算八皇后问题.docx(47页珍藏版)》请在冰豆网上搜索。

并行计算八皇后问题.docx

并行计算八皇后问题

并行计算与多核多线程技术

课程报告

班级__________________

学号_____________

姓名_________________

 

2014年11月26日

评价

实践效果(正确度/加速比)

 

理论基础

 

难度

 

工作量

 

独立性

 

1.N皇后问题并行算法设计与实现

1.1功能描述与解决方案

1.1.1功能描述

八皇后问题是十九世纪著名数学家高斯于1850年提出的。

问题是:

在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。

可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。

1.1.2解决方案

1、此题有多重解法,常见解法有残卷法(即穷举法,但时间复杂度和空间复杂度均为N^N,并不高效)和递归+回溯算法(本次采用此算法)。

2、判断当前放置的皇后“安全”的依据为同行、同列、对角线-\、对角线-/的遍历结果均为TRUE即没有不满足问题条件的皇后存在。

3、第一个线程从第一列第一行的坐标开始放置皇后,其他线程从其他列第一行的元素开始递归放置皇后,每放置一个皇后,判断其是否安全,若“安全”则继续在当前列和(当前行+1)处放置下一个皇后,若不安全则将当前皇后坐标设为0。

4、采用三维数组m[THREAD][QUEENS][QUEENS]来存放棋盘的放置状态,第一维用于保证各线程不会影响其他线程的放置状态,第二、三维用来确定棋盘的规格。

1.2算法设计

1.2.1串行算法设计

/**

*wy_serial_listAllCol:

ListAllTheValidChessTableInSerialWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){for(intx=0;x

m[0][x][y]=1;

if(wy_isOk(m,x,y,0)){

if(y==QUEENS-1){

//print(m,0);

}else

wy_serial_listAllCol(m,y+1);

}

m[0][x][y]=0;

}

}

1.2.2并行算法设计

OpenMP使用parallelfor来调用listFirstCol()函数,listFirstCol再递归调用listSecondCol()函数来实现各线程并行递归回溯

其他语言使用并行区域的办法来保证各线程并行递归回溯

/**

*wy_parallel_listOtherCol:

DetermineTheOtherColsInParallelWay

*

*@paramm[][][]

*@paramy

*@paramthread

*/

staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){

for(intx=0;x

m[thread][x][y]=1;

if(wy_isOk(m,x,y,thread)){

if(y==QUEENS-1){

//print(m,omp_get_thread_num());

}else

wy_parallel_listOtherCol(m,y+1,thread);

}

m[thread][x][y]=0;

}

}

/**

*wy_parallel_listFirstCol:

DetermineTheFirstColInParallelWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty){

#pragmaompparallelfor

for(intx=0;x

//printf("thread_num%d\n",omp_get_thread_num());

m[omp_get_thread_num()][x][y]=1;

if(wy_isOk(m,x,y,omp_get_thread_num())){

wy_parallel_listOtherCol(m,y+1,omp_get_thread_num());

}

m[omp_get_thread_num()][x][y]=0;

}

}

1.2.3理论加速比分析(选作)

在N皇后问题中,加速比一般为Thread数目,最高加速比为N。

因为最多允许N个线程同时运行。

1.3基于OpenMP的并行算法实现

1.3.1代码及注释(变量名名字首字母开头)

//YTUWangYang123-2201258503222OpenMPN-QUEEN

#include"stdafx.h"

#defineQUEENS8/*QUEENSNUM*//*8QUEENSHAVA92RES*/

#defineTHREADS4/*THREADSTOTALNUM*/

/**

*wy_isOk:

CheckTheCurrentQueenSiteValidity

*

*@paramx

*@paramy

*@returnbool-value

*/

staticboolwy_isOk(intm[THREADS][QUEENS][QUEENS],intx,inty,intthread){

inttx,ty;

/*Samerow,returnfalse*/

for(ty=0;ty

if(m[thread][x][ty]==1)returnfalse;

}

/*Samecol,impossible*/

/*Diagonal\,returnfalse*/

tx=x;ty=y;

while(--tx>=0&&--ty>=0){

if(m[thread][tx][ty]==1)returnfalse;

}

/*Diagonal/,returnfalse*/

tx=x;ty=y;

while(++tx=0){

if(m[thread][tx][ty]==1)returnfalse;

}

returntrue;

}

/**

*count:

CurrentCount

*/

staticintcount=1;

/**

*print:

PrintCurrentFinishedChessTable

*

*@paramm[][][]

*@paramthread

*/

staticvoidprint(intm[THREADS][QUEENS][QUEENS],intthread){

printf(">%d\n",count);

count++;

for(inti=0;i

for(intj=0;j

printf("%d",m[thread][i][j]);

}

printf("\n");

}

}

/**

*wy_serial_listAllCol:

ListAllTheValidChessTableInSerialWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){

for(intx=0;x

m[0][x][y]=1;

if(wy_isOk(m,x,y,0)){

if(y==QUEENS-1){

//print(m,0);

}else

wy_serial_listAllCol(m,y+1);

}

m[0][x][y]=0;

}

}

/**

*wy_parallel_listOtherCol:

DetermineTheOtherColsInParallelWay

*

*@paramm[][][]

*@paramy

*@paramthread

*/

staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){

for(intx=0;x

m[thread][x][y]=1;

if(wy_isOk(m,x,y,thread)){

if(y==QUEENS-1){

//print(m,omp_get_thread_num());

}else

wy_parallel_listOtherCol(m,y+1,thread);

}

m[thread][x][y]=0;

}

}

/**

*wy_parallel_listFirstCol:

DetermineTheFirstColInParallelWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty){

#pragmaompparallelfor

for(intx=0;x

//printf("thread_num%d\n",omp_get_thread_num());

m[omp_get_thread_num()][x][y]=1;

if(wy_isOk(m,x,y,omp_get_thread_num())){

wy_parallel_listOtherCol(m,y+1,omp_get_thread_num());

}

m[omp_get_thread_num()][x][y]=0;

}

}

int_tmain(intargc,_TCHAR*argv[]){

intm[THREADS][QUEENS][QUEENS];

/*ParallelPart*/

omp_set_num_threads(THREADS);

clock_tt1=clock();

for(inti=0;i

for(intj=0;j

for(intz=0;z

m[i][j][z]=0;

}

}

}

wy_parallel_listFirstCol(m,0);

clock_tt2=clock();

floatpt=t2-t1;

printf("NQUEEN:

N=%d\n",QUEENS);

printf("ParallelTime=%f\n",pt);

/*SerialPart*/

t1=clock();

for(inti=0;i

for(intj=0;j

for(intz=0;z

m[i][j][z]=0;

}

}

}

wy_serial_listAllCol(m,0);

t2=clock();

floatst=t2-t1;

printf("SerialTime=%f\n",st);

printf("相对加速比=%f\n",st/pt);

getch();

return0;

}

1.3.2执行结果截图(体现串行时间、并行时间和加速比)

(1)小数据量验证正确性的执行结果

N=12SerialTime=498,ParallelTime=1235

相对加速比=2.479

(2)大数据量获得较好加速比的执行结果

N=14SerialTime=20340,ParallelTime=41072

相对加速比=2.019

1.3.3遇到的问题及解决方案

(1)问题一

错误代码及后果

当数组m维数为2维时,无法避免其他线程对当前线程的影响,各线程存在数据竞争,无法准确的描述棋盘放置状态。

正确代码

应将数组设置为3维,第1维为Thread维,避免多线程共同操作同一个棋盘,出现数据竞争。

分析

OpenMP和Intel的CPU兼容很好,所以加速比很理想。

 

1.4基于MPI的并行算法实现

1.4.1代码及注释(变量名名字首字母开头)

//YTUWangYang123-2201258503222MPIN-QUEEN

#include"stdafx.h"

#defineQUEENS8/*QUEENSNUM*//*8QUEENSHAVE92RES*/

#defineTHREADS2/*THREADSTOTALNUM*/

/**

*wy_isOk:

CheckTheCurrentQueenSiteValidity

*

*@paramx

*@paramy

*@returnbool-value

*/

staticboolwy_isOk(intm[THREADS][QUEENS][QUEENS],intx,inty,intthread){

inttx,ty;

/*Samerow,returnfalse*/

for(ty=0;ty

if(m[thread][x][ty]==1)returnfalse;

}

/*Samecol,impossible*/

/*Diagonal\,returnfalse*/

tx=x;ty=y;

while(--tx>=0&&--ty>=0){

if(m[thread][tx][ty]==1)returnfalse;

}

/*Diagonal/,returnfalse*/

tx=x;ty=y;

while(++tx=0){

if(m[thread][tx][ty]==1)returnfalse;

}

returntrue;

}

/**

*count:

CurrentCount

*/

staticintcount=1;

/**

*print:

PrintCurrentFinishedChessTable

*

*@paramm[][][]

*@paramthread

*/

staticvoidprint(intm[THREADS][QUEENS][QUEENS],intthread){

printf(">%d\n",count);

count++;

for(inti=0;i

for(intj=0;j

printf("%d",m[thread][i][j]);

}

printf("\n");

}

}

/**

*wy_serial_listAllCol:

ListAllTheValidChessTableInSerialWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_serial_listAllCol(intm[THREADS][QUEENS][QUEENS],inty){

for(intx=0;x

m[0][x][y]=1;

if(wy_isOk(m,x,y,0)){

if(y==QUEENS-1){

//print(m,0);

}else

wy_serial_listAllCol(m,y+1);

}

m[0][x][y]=0;

}

}

/**

*wy_parallel_listOtherCol:

DetermineTheOtherColsInParallelWay

*

*@paramm[][][]

*@paramy

*@paramthread

*/

staticvoidwy_parallel_listOtherCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){

for(intx=0;x

m[thread][x][y]=1;

if(wy_isOk(m,x,y,thread)){

if(y==QUEENS-1){

//print(m,thread);

}else

wy_parallel_listOtherCol(m,y+1,thread);

}

m[thread][x][y]=0;

}

}

/**

*wy_parallel_listFirstCol:

DetermineTheFirstColInParallelWay

*

*@paramm[][][]

*@paramy

*/

staticvoidwy_parallel_listFirstCol(intm[THREADS][QUEENS][QUEENS],inty,intthread){

intfloorLength=int(floor(double(QUEENS/2)));

if(thread==0){

for(intx=0;x

m[thread][x][y]=1;

if(wy_isOk(m,x,y,thread)){

wy_parallel_listOtherCol(m,y+1,thread);

}

m[thread][x][y]=0;

}

}else{

for(intx=floorLength;x

m[thread][x][y]=1;

if(wy_isOk(m,x,y,thread)){

wy_parallel_listOtherCol(m,y+1,thread);

}

m[thread][x][y]=0;

}

}

}

int_tmain(intargc,char*argv[]){

intm[THREADS][QUEENS][QUEENS];

/*ParallelPart*/

intn=0,done=0;

intthread,size;

doublet1,t2;

MPI_Init(&argc,&argv);/*InitMPI*/

MPI_Comm_size(MPI_COMM_WORLD,&size);

MPI_Comm_rank(MPI_COMM_WORLD,&thread);

for(inti=0;i

for(intj=0;j

for(intz=0;z

m[i][j][z]=0;

}

}

}

while(!

done){

if(thread==0){

t1=clock();

}

MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);

if(n==0){

done=1;

}

wy_parallel_listFirstCol(m,0,thread);

if(n==0)

t2=clock();

}

MPI_Finalize();/*FinishMPI*/

doublept=t2-t1;

printf("NQUEEN:

N=%d\n",QUEENS);

printf(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1