⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proj2_fun1_parallel.c

📁 Parallel Processing Message Passing Genetic Algorithms
💻 C
字号:
//
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>

#define M_NUM 40//the number of migration
#define POPULATION M_NUM*10//population size for each node

#define SOLUTION_BITS 63
#define VARIABLES_BITS 21
#define G_OK 10
#define POOL 10//the number of Pool we want to use

#define G_NUM 1000//generation size
#define K_G_NUM 100//after k generation do migration



int termination_condition = 0;
double start_t;
double end_t;
double communication_time=0;

double total_time=0;
float maxmin,maxmax;
float maxOfAll=0;

float subsum[POPULATION];

float sum;
char gene[POPULATION][SOLUTION_BITS];//

int generation_num=0;
int generation_OK=0;//


//print all the gene
void printgeneall()
{
	int i,j;
	for(i=0;i<POPULATION;i++)
	{
		printf("gene[%i] =",i);
		for(j=0;j<SOLUTION_BITS;j++)
		{
			printf("%c",gene[i][j]);
		}
		printf("\n");
	}
}

//print a line of gene
void printgene(int i)
{
	int j;
	printf("gene[%i] =",i);
	for(j=0;j<SOLUTION_BITS;j++)
	{
		printf("%c",gene[i][j]);
	}
	printf("\n");
  
}

//
//initialize population
void initializePopulation()
{
	int i,j,bit0_1;
	for(j=0;j<POPULATION;j++)
	{
		for(i=0;i<SOLUTION_BITS;i++) 
		{ 
			//
			
			bit0_1=(int)(floor((rand()/(RAND_MAX+1.0))*2)); 

			if(bit0_1==0)
				gene[j][i]='0';
			else
				gene[j][i]='1';
			
		} 
	}
}//end of initializePopulation()



void evaluatePopulation()
{
	float xyz;
	int i,j;
	float x[POPULATION],y[POPULATION],z[POPULATION];
	//
	
	for(i=0;i<POPULATION;i++)
	{
		//printgene(i);
		x[i]=0;
		for(j = 1;j < VARIABLES_BITS;   j ++)   
		{   
			
			if(gene[i][j]=='1')
			{
				x[i]=x[i]+(int)(pow(2,(VARIABLES_BITS-1-j)));
			}
		} 
		//
		if(gene[i][0]=='1')
			x[i]=0-x[i];
		//printf("x[%i]=%f ,",i,x[i]);
		y[i]=0;
		for(j = VARIABLES_BITS+1;j < 2*VARIABLES_BITS;   j ++)   
		{   
			
			if(gene[i][j]=='1')
			{
				y[i]=y[i]+(int)(pow(2,(2*VARIABLES_BITS-1-j)));
			}
		} 
		if(gene[i][VARIABLES_BITS]=='1')
			y[i]=0-y[i];
		//printf("y[%i]=%f ,",i,y[i]);
		z[i]=0;
		for(j = 2*VARIABLES_BITS+1;j < 3*VARIABLES_BITS;   j ++)   
		{   
			
			if(gene[i][j]=='1')
			{
				z[i]=z[i]+(int)(pow(2,(3*VARIABLES_BITS-1-j)));
			}
		} 
		if(gene[i][2*VARIABLES_BITS]=='1')
			z[i]=0-z[i];
		//printf("z[%i]=%f",i,z[i]);

		subsum[i]=0-x[i]*x[i]+1000000*x[i]-y[i]*y[i]-40000*x[i]-z[i]*z[i];
		//printf("subsum[%i]=%f\n",i,subsum[i]);
		sum+=subsum[i];
	}
	//printf("sum=%f",sum);
	
	

}

//check fitness of population
int check(int i)
{	
	float a = (rand()/(RAND_MAX+1.0))*sum;
	if(subsum[i]<sum/POPULATION)
	{
		return 0;
	}
	
	if(a<subsum[i])
		return 1;
	return 0;

}

void selectParents()
{	
	int i = 0,pParents,j ;
	char gene1[POPULATION][SOLUTION_BITS];
	while (i<POPULATION)
	{
		pParents = (int)(floor((rand()/(RAND_MAX+1.0))*POPULATION));
		if(check(pParents))
		{
			for( j =0;j<SOLUTION_BITS;j++)
			{
				gene1[i][j]=gene[pParents][j];
			}
			i++;	
		}
	}
	for (i=0;i<POPULATION;i++)
	{
		//printf("choice gene[%i]",i);
		for(j =0;j<SOLUTION_BITS;j++)
			{
				gene[i][j]=gene1[i][j];
				//printf("%c",gene[i][j]);
			}
		//printf("\n");
	}
	
}

//
void crossOver()
{	
	int i,b,j;
	float c;
	char temp;
	for (i=0;i<POPULATION;i=i+2)
	{ 
		c = rand()/(RAND_MAX+1.0);
		if (c<0.7)
		{ 
			b = (int)(floor((rand()/(RAND_MAX+1.0))*SOLUTION_BITS));
			for ( j=0;j<b;j++)
			{
				temp=gene[i][j];
				gene[i][j]=gene[i+1][j];
				gene[i+1][j]=temp;
			}
		}
	}
}

void mutation()
{	
	int i,j;
	float a1;
	for ( i=0;i<POPULATION;i++)
	{
		for ( j=0;j<SOLUTION_BITS;j++)
		{
			a1 = rand()/(RAND_MAX+1.0);
			if (a1<0.03)
			{	
				if(gene[i][j]=='1')
				{
					gene[i][j]='0';
				}
				else gene[i][j]='1';
			}		
		}
	}
			
}

float maxofG()
{
	float max = subsum[0];
	int i;
	for(i=1;i<POPULATION;i++)
	{
		if(max<subsum[i])
				max=subsum[i];
	}
	return max;
		
}

int termination_conditions()
{
	
	//max=maxofG();
	if(generation_OK>=G_OK)
		return 1;
	else if(generation_num>G_NUM)
		return 1;
	else
		return 0;
}

//in order to easier to compare with sequential algorithm 
//just make the termination condition easier to see the communication cost
int termination_conditions2()
{
	if(generation_num>G_NUM)
		return 1;
	else
		return 0;
}

void migrationto(int dest)
{
	int i,j;
	char buff[M_NUM][SOLUTION_BITS];
	for(j=0;j<M_NUM;j++)
	{
		for(i=0;i<SOLUTION_BITS;i++)
		{
			buff[j][i]=gene[j][i];
			
		}
	}
	start_t=MPI_Wtime();
	MPI_Send(buff, M_NUM, MPI_CHAR, dest, 0, MPI_COMM_WORLD);
	communication_time=communication_time+MPI_Wtime()-start_t;
}
void migrationfrom(int source)
{
	MPI_Status stat; 
	int i,j;
	char buff[M_NUM][SOLUTION_BITS];
	start_t=MPI_Wtime();
	MPI_Recv(buff, M_NUM, MPI_CHAR, source, 0, MPI_COMM_WORLD, &stat);
	communication_time=communication_time+MPI_Wtime()-start_t;
	for(j=0;j<M_NUM;j++)
	{
		for(i=0;i<SOLUTION_BITS;i++)
		{
			gene[POPULATION-1-j][i]=buff[j][i];
			
		}
	}
	

}

void updatecondition()
{
		float maxtemp;
		maxtemp=maxofG();
		if(maxtemp>0)
		{
			if(maxmin>maxtemp)
			{
				maxmin=maxtemp;
			}
			if(maxmax<maxtemp)
			{
				maxmax=maxtemp;
			}
			
			if((maxmax-maxmin)<(0.05*maxmax))
			{
				generation_OK++;
			}
			else
			{
				maxmin=maxtemp;
				maxmax=maxtemp;
				generation_OK=0;
			}
		}
}

int main(int argc, char **argv)
{
	char idstr[32];
	char buff[SOLUTION_BITS];
	float maxOfTemp;
	float infopass[1];
//	float MPI_maxOfTemp[1];
	int numprocs;
	int myid;
	int i,j;
	int k;
    double start_t1,start_t_all,compute_time;
	
	MPI_Status stat; 
	MPI_Init(&argc,&argv); 
	MPI_Comm_size(MPI_COMM_WORLD,&numprocs); 
	MPI_Comm_rank(MPI_COMM_WORLD,&myid);

	
	if(numprocs==1)
	{
		printf("please choose more nodes to run this parallel algorithm");
	}
	else
	{
		if(myid==0)
		{
			printf("the population for each node is %d\n",POPULATION);
			printf("the number of migration for each time is %d\n",M_NUM);
			
			printf("the number of generation for each node is %d\n",G_NUM);
			printf("after %d generation do migration\n",K_G_NUM);
			
			
		}

		start_t_all=MPI_Wtime();//each node's compute time start
		
		//use with rand() to get randam number
		srand( (unsigned)time( NULL ) );

		initializePopulation(POPULATION);
		//printgeneall();
		evaluatePopulation();
		//need to use if change termination condition.
		//maxmin=maxofG();
		//maxmax=maxofG();
		
		maxOfTemp=maxofG();
		if(maxOfTemp>maxOfAll)
		{
			maxOfAll=maxOfTemp;
		}
		while(!termination_conditions2())
		{
			
			generation_num++;
			selectParents();
			crossOver();
			mutation();
			//start migration
			if(generation_num%K_G_NUM==0)
			{
				
				if(myid!=(numprocs-1))
				{
					
					migrationto(myid+1);//send message
		
				}
				else
				{
					
					migrationto(0);//send message
					
				}

				if(myid==0)
				{
					
					migrationfrom(numprocs-1);//receive message
					
				}
				else
				{
					
					migrationfrom(myid-1);//receive message
					
				}
			//end of migration
				
			}
			//

			evaluatePopulation();
			maxOfTemp=maxofG();
			if(maxOfTemp>maxOfAll)
			{
				maxOfAll=maxOfTemp;
			}

			//update termination_conditions(in order to consider more about the communication cost the condition changes)
			//updatecondition()  
			

		}//End of while(!termination_conditions())
		
		
		
		

		if(myid!=0)
		{
			infopass[0]=maxOfAll;
			start_t=MPI_Wtime();
			MPI_Send(infopass, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD);
			communication_time=communication_time+MPI_Wtime()-start_t;
			compute_time=compute_time+MPI_Wtime()-start_t_all;//each node's compute time end
			//printf("        node %d compute time=%f\n",myid,compute_time-communication_time);
			//printf("++++++++node %d : communication_time=%f\n",myid,communication_time);
			
		}
		else
		{	//
			//receive all other max value from other nodes and choose the largest.
			
			
			for(i=1;i<numprocs;i++)
			{
				
				start_t=MPI_Wtime();
				MPI_Recv(infopass, 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD, &stat);
				communication_time=communication_time+MPI_Wtime()-start_t;
				
				//printf("Data from node %d received\n",i);
				maxOfTemp=infopass[0];
				total_time+=infopass[1];
				if(maxOfTemp>maxOfAll)
				{
					maxOfAll=maxOfTemp;
				}
			}
			
			total_time+=MPI_Wtime()-start_t_all;
			printf("master node is finished getting the result\n",myid);
			printf("   max = %f\n",maxOfAll);
			printf("master node's communication_time=%f\n",communication_time);
			
			printf("total_time=%f\n",total_time);
		}
	}
		
		
	
	MPI_Finalize();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -