📄 parallel.cc
字号:
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
//#include "Optimal.h"
//#include "optimal.cpp"
const float pi = 3.141;
const float PMUTATION = 0.3;
const int E_CUT = 1000;
typedef struct mypoint
{
int x;
int y;
}CPoint;
//float fit_slave_value;
//int *buffer_slave = new int[2*num];
//int *buffer_host;
int hehe;
int MAXPOINT = 24; //最多点源数
float high[256][128]; //256*128高程值
bool Flag[256][128]; //是否被覆盖的标志
float m_maxdis[72]; //某个点源到园上72个点的最大距离
float m_shademax[72]; //某个点的最大遮蔽角
int Global_area = 19879; //整个陆地面积
int Region_Flag[256][128]; //考虑是否可以写成char Region_Flag
int SingleSpotArea[256][128]; //不考虑重叠单点覆盖
//int **boundary; //为什么这里不用数组呢??因为我在这里还不知道大小,所以要动态分配
int Ac = 2070;
int size = 20; //种群大小
int maxiteration = 100; //迭代次数
int *best; //最优个体指针
int Best_Fit; //最优个体覆盖面积
char *source;
//以下定义遗传算法中用到的变量
int best_index; //最好的个体的行索引值
int best_overcastting;
int **individual_vector; //二十个个体点源位置矩阵
int **newindividual_vector; //四十个个体点源位置矩阵
float *fit; //二十个个体适应度数组 //从进程主要分配fit和individual_vector
float *new_fit; //四十个个体适应度数组
int **binary; //二进制编码矩阵
int num; //点源个数
float a = 0; //NewFitFunction中的权重
bool flag;
//调用函数中用到的变量,有些也设为全局变量
int iter;
//函数原型
//void Fill(CPoint p);
void FindTheSource();
float randf();
void Initial();
int FitFunction(int *X, int Dem);
void InitialArray();
//void Initial(int **individual_vector,int Num,int Size);
//void FlagRegion();
float NewFitFunction(int *X, int Dem,float a);
int CalAk(CPoint pt);
void Fill(CPoint pt);
//void CalAc();
//char** coding(int **individual_vector, int size,int num);
int MinFit_index(float *fit, int size);
int MaxFit_index(float *fit, int size);
//void GlobalGA(CView *view);
int GASearch();
//void DrawFig(CDC *pDC,int *x,int num);
//CPoint AddPoint();
void Readfile();
bool IsPointInPolygon(float x,float y,int **polygon,int PointNumber);
float DistanceOfTwoPoints(float x1,float y1,float x2,float y2);
float CrossProductOfTwoLine(float x1,float y1,float x2,float y2,float x3,float y3);
bool WithDeadArea(int cs);
//double FitFunction(int *X,int Dem);
//double randf();
//void CalArea(CPoint pt);
void Shade(CPoint pt);//计算每一点的遮蔽角
void MaxHDis(CPoint pt); //该函数中涉及到等射束高度图中的高度
void AdjustDis(CPoint pt);
//bool IsPointInBoundary(CPoint pt); ///判断点是否在多边形内
long RegionArea();
void Coding();
//交叉操作
void CrossOver();
//变异
void Mutation();
//解码 比较费时
void Decoding();
//constrain restrict
void Constrain();
//new_fit[i] = FitFunction(newindividual_vector[i],num);
void Selection();
void SaveTheBest();
//以上是函数原型
//********************************************************************//
int main(argc,argv)
int argc;
char** argv;
{
int rank;
int np;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&np); //不知道np是否包括0号进程.
Readfile();
int nSize = size / (np-1); //np-1是除去主进程以后,从进程数量
//nSize是每个从进程应该分配的数组数目,
//注意!!最后一个从进程分配size%(np-1)个数组
if(rank == 0)
master();
else
slave();
MPI_Finalize();
}
int master(void)
{
for(hehe = 10; hehe > 0; hehe--)
{
num = 16;
a = float(hehe)/10;
while( num <= MAXPOINT )
{
cout<<a<<" "<<num<<endl;
//InitialArray(); //快 //根据num的值来初始化遗传算法中用到的数组和矩阵
srand((unsigned)time(NULL));
best_index = GASearch(); //GASearch()中有主进程的消息发送和接收函数
best = individual_vector[best_index]; // 把适应度最高的个体的地址付给best指针
//这里要注意!!!!!!!!!!!!!!!!!!
//best可以用于数组的任何运算
SaveTheBest();
best_overcastting = FitFunction(best,num);
flag = WithDeadArea(best_overcastting);
//释放内存
for(int k=0;k<size;k++)
{
// delete[] binary[k];
delete[] individual_vector[k];
}
// for( k=0;k<2*size;k++)
// delete[] newindividual_vector[k]; //why??????????
//delete[] binary;
delete[] individual_vector;
delete[] fit;
//delete[] new_fit;
//delete[] newindividual_vector;
cout<<"When num = "<<num<<" The memory has been released!\n"<<endl;
if(flag)
break;
else
num++;
}
}
}
int slave()
{
while(1)
{
if(rank < np -1)
{
fit = new float*[nSize];
individual_vector = new int*[nSize];
for(int i = 0; i <nSize; i++)
individual_vector[i] = new int[2*num];
MPI_Recv(individual_vector,2*nSize*num,MPI_INT,0,tag,MPI_COMM_WORLD,); //每一个从进程接受自己标识的个体,放入buffer_slave缓冲区
for(i = 0; i < nSize; i++)
fit[i] = NewFitFunction(individual[i],num,a);
MPI_Send(&fit,2*nSize,MPI_INT,0,tag,MPI_COMM_WORLD,); //发给主进程
}
else
{
nSize = size%(p-1);
fit = new float*[nSize];
individual_vector = new int*[nSize];
for(int i = 0; i <nSize; i++)
individual_vector[i] = new int[2*num];
MPI_Recv(individual_vector,2*nSize*num,MPI_INT,0,tag,MPI_COMM_WORLD,); //每一个从进程接受自己标识的个体,放入buffer_slave缓冲区
for(i = 0; i < nSize; i++)
fit[i] = NewFitFunction(individual[i],num,a);
MPI_Send(&fit,2*nSize,MPI_INT,0,tag,MPI_COMM_WORLD,); //发给主进程
}
}
}
int GASearch()
{
/**************************************************************************
参数:num表示点源的个数;2*num 维数;individual_vector存放位置向量
***************************************************************************/
//局部变脸定义
//float a = A;
//int num = Num;
//int size=Size;
iter=0; //迭代次数初始值为0
//int MAXITER=Iteration; //size为种群大小
//int *best_individual = new int[2*num]; //推出循环时需要释放内存
int j;
// int min =0;
int temp = 0;
int max = temp; //初始时最大值设为0号元素
//不初始化也无所谓
/* for( int i = 0; i < 2*size; i++)
{
new_fit[i] = 0;
}
*/
//double *Statistic_fit =new float[size]; //推出循环时需要释放内存
//double *Cumulative_fit = new float[size]; //推出循环时需要释放内存
//种群初始化****************费时***********************
//Initial(individual_vector, Num, Size);
//要用的时候才分配内存
individual_vector = new int* [size]; //主进程分配空间
for(int i = 0; i < size; i++)
individual_vector[i] = new int[2*num];
fit = new float[size];
Initial(); //主进程初始化矩阵
//Random_Initial(individual_vector, Num, Size);
//FengWO_Init(individual_vector, Num, Size);
cout<<"Initial success"<<endl;
FILE *f;
char dest[30] = "/home/qyf/qdata/GA/EveryFit/";
FindTheSource();
strcat(dest,source);
f = fopen(dest,"w");
//主进程开始发送消息
int nStart = 1;
//发送给1至np-2号进程的数组
while(nStart < np-1)
{
MPI_Send(individual_vector+2*(nStart-1)*num*nSize,2*num*nSize,MPI_INT,nStart,tag,MPI_COMM_WORLD);
nStart++;
}//while
//发送消息给np-1号进程的数组
MPI_Send(individual_vector+2*(nStart-1)*num*nSize,2*num*Size%(np-1),MPI_INT,nStart,tag,MPI_COMM_WORLD);
MPI_Recv(); //从结点收回计算得到的结果,放入fit数组
//for( i = 0; i < size; i++ )
// fit[i] = NewFitFunction(individual_vector[i],num,a); //怎么计算出来全是0
//fit[i] = FitFunction(individual_vector[i],num);
temp = MaxFit_index(fit,size); //快//找出适应度最大的个体,
//让max等于它的索引值 ,如果不迭代就直接返回这个max
max = temp;
fprintf(f,"%f\n",fit[max]);
cout<<fit[max]<<endl;
while(iter < maxiteration) //如果改成第二种适应度这里需要修改
{
new_fit = new float[2*size];
newindividual_vector = new int* [size*2];
for( i = 0; i < 2*size; i++)
{
newindividual_vector[i] = new int[2*num];
}
//////////////////////////////////////////////////////////////////////////////
//以下是裴老师教的方法
//////////////////////////////////////////////////////////////////////////////
//复制父代的20个个体到newindividul_vector,把fit也复制到new_fit;
for( i = 0; i < size; i++ )
{
for( j = 0; j < 2*num; j++ )
{
newindividual_vector[i][j] = individual_vector[i][j];
}
new_fit[i] = fit[i];
}
//已经赋给了newindividual_vector,因为在交叉操作那里还要用,所以这里先不释放了
delete []fit;
//编码之前分配binary内存
binary = new int*[size];
for(i = 0; i < size; i++)
binary[i] = new int [15*num];
//编码之前binary数组先清零
for( i=0; i < size; i++)
for(int j = 0; j < 15*num; j++)
binary[i][j] = 0;
//交叉之前先编码
Coding();
for( i =0; i < size; i++)
delete individual_vector[i];
delete individual_vector;
//交叉操作
CrossOver();
//变异
Mutation();
//解码 **************比较费时*********s************
Decoding();
for(i = 0; i < size; i++)
delete []binary[i];
delete []binary;
//constrain restrict***************比较费时*********************
Constrain();
for(int i = 1; i <np; i++) //多少个结点,size就是多大
{
buffer_host = individual_vector[i];
MPI_Send(buffer_host,2*num,MPI_INT,i, , ,); //把第i个个体的数组发到第i个结点,后面两个参数不知道怎么写
}
for( i = 1; i <np; i++)
{
MPI_Recv(fit[i-1],2*num,MPI_INT,i,,,);
}
//new_fit[i] = FitFunction(newindividual_vector[i],num);
Selection();
max = 0;
iter++;
cout<<"The "<<iter<<"-th "<<" iteration finished!"<<endl;
fprintf(f,"%f\n",fit[max]);
cout<<fit[max]<<endl;
}
//delete []Statistic_fit;
//delete []Cumulative_fit;
fclose(f);
return max;
}
void Readfile()
{
FILE *fp1;
//FILE *fp2;
//FILE *fp3;
FILE *fp4;
FILE *fp5;
//int bnum; //局部变量,边界点个数
//int bx,by; //保存boundary数组时用到的变量
fp1 = fopen("/home/qyf/lastdata/shenzhen128x256.txt","r");
//fp2 = fopen("f:/lastdata/optpoint5.txt","r");
// fp3 = fopen("f:/lastdata/boundary.txt","r");
fp4 = fopen("/home/qyf/qdata/Region2.txt","r");
fp5 = fopen("/home/qyf/qdata/CalSingleSpot2.txt","r");
//读Region_Flag和SingleSpotArea之前先初始化
for(int i_temp = 0; i_temp < 256; i_temp++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -