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

📄 gaqueen.cpp

📁 这是一个解决皇后问题的遗传算法
💻 CPP
字号:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define Critical 1e-3
#define MAX_QUEENS 500		

int n ;                     //实际的皇后数
int goal ;					// 种群进化的目标,达到 goal 即返回程序
clock_t start, end ;		
time_t	start_time, end_time ;

typedef struct 
{
	int queen[MAX_QUEENS] ;
	int Fitness	;
} Population ; 

Population population[30+MAX_QUEENS/10] ;
int size ;           
int totFitness ;    

void init ()
{
	//srand (time(0)) ;
	printf("请输入皇后的个数:");
	scanf ("%d", &n) ;
	if(n<4)
	{
		printf("输入的皇后数最少为4!\n");
		exit(0);
	}
	goal = n;
	size = 30 + n / 10 ;
	start = clock () ;
	time (&start_time) ;	
	printf("Start: \t %s", ctime(&start_time));
}

int compare(const void *a,const void *b)
{
  return ((Population *)b)->Fitness - ((Population *)a)->Fitness;
}  

void UpdateFitnessScore (Population *p) 
{
	int i,r=0;
	int ru[2*MAX_QUEENS],rd[2*MAX_QUEENS];

	for(i=0;i<2*n;i++)
	{
		ru[i]=0;
		rd[i]=0;
	}
	for(i=0;i<n;i++)
	{
		ru[p->queen[i]-i+n]++;
		rd[p->queen[i]+i]++;
	}
	for(i=0;i<2*n;i++)
	{
		if(ru[i]>1) r+=ru[i]-1;
		if(rd[i]>1) r+=rd[i]-1;
	}
	p->Fitness=n-r;

}


void CreateMultiStartPopulation ()
{	
	int loop, i, j ;
	int tmp[MAX_QUEENS] ;
	
	for (loop = 0 ; loop < size ; loop ++)	
	{

		for (i = 0 ; i < n ; i++)
				tmp[i] = i ;

			for (i = 0 ; i < n ; i++)
			{
				j = rand() % (n - i) ;
				population[loop].queen[i] = tmp[j] ;
				tmp[j] = tmp[n - i - 1] ;
			}
			UpdateFitnessScore(&population[loop]) ;
	}
	/*
	int i,j,flag,loop;
	for(loop=0;loop<size;loop++)
	{
		flag=0;
		population[loop].queen[0]=(int)abs(rand()%n);
		for(i=1;i<n;i++)
		{
			do
			{
				population[loop].queen[i]=(int)abs(rand()%n);
				for(j=0;j<i;j++)
				{
					if(population[loop].queen[i]==population[loop].queen[j])
					{
						flag=1;
						break;
					}
					else flag=0;
				}
			}while(flag);
		}
	    UpdateFitnessScore(&population[loop]) ;
	}*/
}

// 双亲遗传中的变异算子
void MultiMutate (Population* p)
{
	int i, j, k,swap ;
	Population baby ;

	baby = *p ;
	for (i = 0 ; i < n / 4 ; i++)
	{
		do 
		{
			j = rand() % n ;
			k = rand() % n ;
		} while (j == k) ;	
			
		swap = baby.queen[k] ;
		baby.queen[k] = baby.queen[j] ;
		baby.queen[j] = swap ;

		UpdateFitnessScore(&baby) ;
		if (baby.Fitness > p->Fitness || (double)rand() / RAND_MAX < Critical)
		{
			*p = baby ;
			break ;
		}
	}
}

int RouletteWheelSelection()
{
	int selection = 0;
	int i ;

	double slice = (double)rand() / RAND_MAX;
	double addFitness = 0;
	for(i = 0; i < size ; i++)
	{
		addFitness +=  (double)population[i].Fitness / totFitness ;
		if(addFitness > slice)
		{
			selection = i;
			break;
		}
	}
	return selection;
}

void CrossOverFM (Population father, Population mother, Population *baby)
{
	int flag[MAX_QUEENS] ;
	int pos1, pos2, tmp ;
	int i, j ;

	do 
	{
		pos1 = rand() % n ;
		pos2 = rand() % n ;
	} while (pos1 == pos2) ;
	
	if (pos1 > pos2) { tmp = pos1 ; pos1 = pos2 ; pos2 = tmp; }

	for (j = 0 ; j < n ; j ++)
		flag[j] = 0 ;
	for (j = pos1; j <= pos2; j++)
		flag[father.queen[j]] = 1 ;

	for(i = 0, j = 0 ; i < n ; i++)
	{
		if (i < pos1 || i > pos2) {
			while (flag[mother.queen[j]]) j++ ;
			baby->queen[i] = mother.queen[j] ;
			j ++ ;
		}
		else baby->queen[i] = father.queen[i] ;
	}
	UpdateFitnessScore (baby) ;
}

void CrossOver () 
{
	int i ;
	int father, mother ;
	Population p[30 + MAX_QUEENS / 10] ;
	int count ;

	totFitness = 0 ;
	for (i = 0 ; i < size ; i++)
		totFitness += population[i].Fitness ;
	
	for (count = 0 ; count < size ; count++)
	{
		father = RouletteWheelSelection () ;
		mother = RouletteWheelSelection () ;
		CrossOverFM (population[father], population[mother], &p[count]) ; // 杂交,后代保存
	}

	for (count = 0 ; count < size ; count++)
		population[count] = p[count] ;
	
}

void PrintQueens (Population p)
{	
	int i, j ;  	
	printf("One solution looks like : \n") ;
	for (i = 0 ; i < n ; i++)
	{
		for (j = 0 ; j < n ; j++)
		{
			if (j == p.queen[i]) printf ("%d  ",j+1);
			else printf ("0  ") ;
		}
		printf ("\n") ;
	}
}

void main ()
{
	while(true)
	{
		int count=0;
		double secs ;
		init() ;	  
		CreateMultiStartPopulation() ;
			
		while (1)
		{
			count++;
			qsort(population, size, sizeof(Population), compare) ;
			MultiMutate (&population[0]) ;
			MultiMutate (&population[1]) ;
			if (population[0].Fitness == goal || population[1].Fitness ==  goal)
				break ;
			CrossOver () ;
		} 
		end = clock () ;
		time (&end_time) ;
		printf ("End:  \t %s", ctime(&end_time));
		secs = (double)(end - start) / CLOCKS_PER_SEC ;
        printf("Calculations took %.3lf second%s.\n", secs, (secs < 1 ? "" : "s"));
		printf("Generation is %d\n",count);
		PrintQueens(population[0].Fitness == goal ? population[0] : population[1]) ;
	}

}

⌨️ 快捷键说明

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