当前位置:文档之家› 高性能计算实验报告

高性能计算实验报告

高性能计算练习实验报告A组:一.问题描述A02. 从键盘输入一个无符号长整型数n,产生一个长度为n,取值在[0,1]之间的随机实数数组,计算其去掉一个最大值、去掉一个最小值,hy剩下n-2个值的平均值。

二.算法设计分为两个线程,每个线程负责查找一半的数中最小的和最大的,并且统计所有的数的和,然后由0号线程进行两个最小的(最大的)数的比较,找出整个数组中最大和最小的数,最后由0号线程取两个和,减去最大最小数,求平均值。

三.重点及难点1. 线程之间的通信。

2. 每个线程都要计算总和,并找出最大最小数。

3. 0号线程完成最后的统筹工作。

四.代码#include "mpi.h"#include <iostream>#include <algorithm>using namespace std;double num[100];void init(double num[], int len){for (int i = 0; i < 100; i++) {num[i] = (double)(rand() % 100) / 100.0;}MPI_Bcast(num, len, MPI_DOUBLE, 0, MPI_COMM_WORLD);}void proc(int start, int end, double &Min, double &Max, double &Sum){for (int i = start; i < end; i++) {Max = Max > num[i] ? Max : num[i];Min = Min < num[i] ? Min : num[i];Sum += num[i];}}int main(int argc, char* argv[]){int rank, np;MPI_Status status;MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &np);init(num, 100);double Min = 1.1, Max = -0.1, Sum = 0.0;double tMin, tMax, tSum;if (rank == 0) {proc(0, 50, Min, Max, Sum);tMin = Min, tMax = Max, tSum = Sum;MPI_Recv(&Min, 1, MPI_DOUBLE, 1, 1, MPI_COMM_WORLD, &status);tMin = tMin < Min ? tMin : Min;MPI_Recv(&Max, 1, MPI_DOUBLE, 1, 10, MPI_COMM_WORLD, &status);tMax = tMax > Max ? tMax : Max;MPI_Recv(&Sum, 1, MPI_DOUBLE, 1, 20, MPI_COMM_WORLD, &status);tSum += Sum;printf("Cal: %lf, %lf, %lf\n", tMin, tMax, (tSum - tMin - tMax) / 98.0);} else {proc(51, 100, Min, Max, Sum);MPI_Send(&Min, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);MPI_Send(&Max, 1, MPI_DOUBLE, 0, 10, MPI_COMM_WORLD);MPI_Send(&Sum, 1, MPI_DOUBLE, 0, 20, MPI_COMM_WORLD);}MPI_Finalize();return 0;}五.结果分析结果正确B组:一. 问题描述B08.(八皇后问题)在8*8格的棋盘上,放置8个皇后。

要求每行每列放一个皇后,而且每一条对角线和每一条反对角线上最多只能有一个皇后,即对同时放置在棋盘的任意两个皇后11(,)i j 和22(,)i j ,不允许1212()()i i j j -=-或者1122()()i j i j +=+的情况出现。

二. 算法设计用一个一维数组完全可以标示整个棋盘。

要注意的是,由于每一行每一列都不重复,即数组中存放的必是一个由0-7组成的全排列。

采用一维数组的全排列,解决了同一行无重复棋子(一维数组来保证,因为数组每个下表只对应一个元素),同一列无重复棋子(全排列来保证,因为全排列每个元素在数组中只出现一次),这样先将八皇后问题转化成了求解一维数组全排列问题。

三. 重点及难点1. 当要判断第七行,即数组下标是6的行元素与其对角线上的棋子是否有冲突,仅仅需要判断其试探棋子向前做加(或减)操作,获得的值是否与相应位置相同即可。

2. 在计算全排列的时候,增加一个flags 数组,用来标记当前第n 个元素是否被占用。

四. 关键代码#include "stdafx.h" #include<iostream> #include<fstream> #ifndef MPICH_SKIP_MPICXX #define MPICH_SKIP_MPICXX #endif #include <mpi.h> using std::cout;using std::endl;using std::cerr; using std::ofstream;using std::ifstream; #define N 8void outPut(const int & size,int * array,ofstream & file) {for(int i = 0 ; i < size ; i++) {file<<array[i]<<" ";} file<<endl; }bool isContact(const int &deep, const int * const &array){ int temp;for(int i = 1 ; i < deep+1 ; i++){temp = array[deep-i];if(array[deep] -i == temp || array[deep] + i == temp )return true;}return false;}void range(const int & size, const int &deep,int * const &flags,int * &array,int &count, ofstream &file) {for(int i = 0 ; i < size ; i++){if(!flags[i]){array[deep] = i;if(deep !=0){if(isContact(deep,array))continue;}flags[i] = 1;if(deep == size-1){outPut(size,array,file);count++;}else{range(size,deep+1,flags,array,count,file);array[deep] = -1;}flags[i] = 0;}}}void mpi_range(const int & size,int * &flags,int * &array,const int &myId){ofstream file;file.open("temp.txt",std::ios::out | std::ios::app);flags = new int[N];array = new int[N];memset(flags,0,sizeof(int)*N);memset(array,-1,sizeof(int)*N);flags[myId] = 1;array[0] = myId;int count = 0 ;int totalCount = 0;range(N,1,flags,array,count,file);MPI_Reduce(&count,&totalCount,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);if(myId == 0)cerr<<totalCount<<endl;file.close();}int _tmain(int argc, char* argv[]){int size;int myId;ofstream file;MPI_Init(&argc,&argv);MPI_Comm_size(MPI_COMM_WORLD,&size);MPI_Comm_rank(MPI_COMM_WORLD,&myId);int *flags;int *array;file.open("temp.txt");file.close();mpi_range(N,flags,array,myId);MPI_Finalize();return 0;}五.结果分析n皇后问题是个np难问题,当皇后的数量增多,问题的复杂度会以n!的方式递增。

相关主题