遗传算法

generic.cpp:
/////////////////////////////////////////////////////////////////////
///
///    SIMPLE GENERIC ALGORITHM
///
/////////////////////////////////////////////////////////////////////

#include "generic.h"

int const FunctionMode = MAXIMIZATION;
int const PopSize = 80;   
int const MaxGeneration = 200;     //最大代数
double Pc = 0.7;     //交叉的概率
double Pm = 0.05;    //突变的概率
int generation;
int best_index;
int worst_index;
struct individual bestindividual;
struct individual worstindividual;
struct individual currentbest;
struct individual population[PopSize];

int g;
////////////////////////////////////////////////



//
// 遗传算法
// 
int generic()
{
	srand(time(0));
	generation = 0;
	GenerateInitialPopulation();
	EvaluatePopulation();
	while (generation < MaxGeneration)
	{
		generation++;
		GenerateNextPopulation();
		EvaluatePopulation();
		PerformEvolution();
	//	OutputTextReport();
	}

//	printf("gen:%d, %d\n", );
	return 0;

}



// 初始化函数,对种群中每个个体中的每个基因,都用rand函数来随机初始化。
void GenerateInitialPopulation()
{
	int i, j;
	for (i=0; i<PopSize; i++)
	{
		for (j=0; j<CHROMLENGTH; j++)
		{
			population[i].chrom[j] = ((rand()%10)<5)?'0':'1';

		}
		population[i].chrom[CHROMLENGTH]='\0';
	}

}


//生成下一代
void GenerateNextPopulation()
{
	SelectionOperator();
	CrossoverOperator();
	MutationOperator();
}



void EvaluatePopulation()
{
    CalculateObjectValue();
	CalculateFitnessValue();
	FindBestAndWorstIndividual();

}

//解码:二进制转化为长整型long
long DecodeChromosome(char *string, int point, int length)
{
	int i;
	long decimal = 0L;
	char *pointer;
	for (i=0,pointer=string+point; i<length; i++,pointer++)
	{
		decimal += (*pointer - '0')<<(length - 1 - i);
	}

	return (decimal);

}

//
// f(x1, x2) = 100 * (x2^2-x2)^2 + (1-x1)^2;
// max: f(-2.048, -2.048) = 3905.926227
// 由population[i].chrom中的二进制值,解码,函数运算后,
// 将结果存到population[i].value中去
void CalculateObjectValue()
{
	int i;
	long temp1, temp2;
	double x1, x2;

	for (i=0; i<PopSize; i++)
	{
		// 由二进制序列转化为long型的 x1, x2
		temp1 = DecodeChromosome(population[i].chrom, 0, LENGTH1);
		temp2 = DecodeChromosome(population[i].chrom, LENGTH1, LENGTH2);
		
		// 抽样值还原为原定义域内的值,
		// 原定义域:- 2.048:2.048, 区间长度4.096
		x1 = 4.096 * temp1 / 1023.0 - 2.048;
		x2 = 4.096 * temp2 / 1023.0 - 2.048;
		population[i].value = 100 * (x1*x1 - x2) * (x1*x1 - x2) + (1 - x1)*(1 - x1);


	}

}

//
// 适应度计算,由population[i].value算出适应度population[i].fitness
// 需要 知道,是求最大值还是求最小值:MAXIMIZATION,MINIMIZATION
// 
void CalculateFitnessValue()
{
	int i;
	double temp;

	for (i=0; i<PopSize; i++)
	{
		if (FunctionMode == MAXIMIZATION)
		{
			if ((population[i].value + Cmin) > 0.0)
			{
				temp = Cmin + population[i].value;
			}
			else
			{
				temp = 0.0;
			}
		}
		else if (FunctionMode == MINIMIZATION)
		{
			if (population[i].value < Cmax)
			{
				temp = Cmax - population[i].value;
			}
			else
			{
				temp = 0.0;
			}
		}

		population[i].fitness = temp;
	}
}

// 已经算好了适应度,计算出最佳的和最差的,以及当前最佳的
// 
void FindBestAndWorstIndividual()
{
	int i;
	double sum = 0.0;
	bestindividual = population[0];
	worstindividual = population[0];

	for (i=1; i<PopSize; i++)
	{
		if (population[i].fitness > bestindividual.fitness)
		{
			bestindividual = population[i];
			best_index = i;
		}
		else if (population[i].fitness < worstindividual.fitness)
		{
			worstindividual = population[i];
			worst_index = i;
		}

		sum += population[i].fitness;
	}

	if (generation == 0)
	{
		g = 0;
		currentbest = bestindividual;
	}
	else if (bestindividual.fitness > currentbest.fitness)
	{
		currentbest = bestindividual;
		g = generation;
	}
}


// 进化,用“史上最好”代替"当前最差"
void PerformEvolution()
{
	if (bestindividual.fitness > currentbest.fitness)
	{
		currentbest = population[best_index];
	}
	else
	{
		population[worst_index] = currentbest;
	}
}

// 选择算法
void SelectionOperator()
{
	int i, index;
	double p, sum = 0.0;
	double cfitness[PopSize];    // 归一化适应度,也就是概率
	struct individual newpopulation[PopSize];

	// 算出总的适应度
	for (i=0; i<PopSize; i++)
	{
		sum += population[i].fitness;
	}

	// 算出归一化适应度
	for (i=0; i<PopSize; i++)
	{
		cfitness[i] = population[i].fitness / sum;
	}

	// 算出归一化适应度的前n项和
	for (i=1; i<PopSize; i++)
	{
		cfitness[i] = cfitness[i - 1] + cfitness[i];
	}

	for (i=0; i<PopSize; i++)
	{
		p = rand()%1000/1000.0;  // 0-1 之间,3位小数
		index = 0;
		while (p > cfitness[index])
		{
			index++;
		}
		newpopulation[i] = population[index];
	}

	// 赋值,新一代正式生成
	for (i=0; i<PopSize; i++)
	{
		population[i] = newpopulation[i];
	}


}



// 交叉互换
void CrossoverOperator()
{
	int i, j;
	int index[PopSize];
	int point, temp;
	double p;
	char ch;

	for (i=0; i<PopSize; i++)
	{
		index[i] = i;
	}
	
	// index数列中的每一个元素,都随机指定数列中在它之后的另一元素,
	// 然后两者互换,目的是打乱数组,实现两两配对的随机
	for (i=0; i<PopSize; i++)
	{
		point = rand()%(PopSize - i);
		temp = index[i];
		index[i] = index[point + i];
		index[point + i] = temp;	
	}

	for (i=0; i<PopSize - 1; i+=2)
	{
		p=rand()%1000/1000.0;
		if (p<Pc)
		{
			// point从1到20;意味着从point到最后一个,这么一段要互换
			point = rand()%(CHROMLENGTH - 1) + 1;
			for (j=point; j<CHROMLENGTH; j++)
			{
				ch = population[index[i]].chrom[j];
				population[index[i]].chrom[j] = population[index[i+1]].chrom[j];
				population[index[i+1]].chrom[j] = ch;

			}
		}
	}
}


// 突变
void MutationOperator()
{
	int i, j;
	double p;

	for (i=0; i<PopSize; i++)
	{
		for (j=0; j<CHROMLENGTH; j++)
		{
			p = rand()%1000/1000.0;

			if (p<Pm)
			{
				population[i].chrom[j] = (population[i].chrom[j] == '0')?'1':'0';
			}
		}
	}
}

// 输出结果
void OutputTextReport()
{
	int i;
	double sum;
	double average;




	sum = 0.0;
	for (i=0; i<PopSize; i++)
	{
		sum += population[i].value;
	}

	average = sum/PopSize;

	printf("gen=%d, avg=%f, best=%f,", generation, average, currentbest.value);

	printf("chromosome=");

	for (i=0; i<CHROMLENGTH; i++)
	{
		printf("%c", currentbest.chrom[i]);
	}

	printf("\n");


}

generic.h:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
//常量
#define    POSIZE     500    //M,群体规模
#define    MAXIMIZATION    1    //maximization falg
#define    MINIMIZATION    2    //minimization flag


//
#define    Cmax    100    //最大值
#define    Cmin    0    //最小值
#define    LENGTH1    10     //第一个自变量采量化编码后的二进制长度
#define    LENGTH2    10     //第二个自变量采量化编码后的二进制长度
#define    CHROMLENGTH    (LENGTH1+LENGTH2)    //总长度


// 个体
struct individual
{
	char chrom[CHROMLENGTH + 1];
	double value;
	double fitness;
};

int generic();

void GenerateInitialPopulation();

void GenerateNextPopulation();
//GenerateNextPopulation
void SelectionOperator();
void CrossoverOperator();
void MutationOperator();

void EvaluatePopulation();
//EvaluatePopulation
void CalculateObjectValue();
void CalculateFitnessValue();
void FindBestAndWorstIndividual();



long DecodeChromosome(char *string, int point, int length);
void PerformEvolution();



void OutputTextReport();

main.cpp:
#include "generic.h"

int gg[1000];
double cc[1000];
extern struct individual currentbest;
extern int g;
///////////////////////////////////
///主函数

int main()
{
	int i;
	double sum = 0;
	double f = 0.0;

	for (i=0; i<1000; i++)
	{
		gg[i] = g;
		generic();
		cc[i] = currentbest.value;
		printf("best:%f,index:%d\n", cc[i], gg[i]);
		Sleep(1500);

	}

	for (i=0; i<1000; i++)
	{
		if (cc[i] > 3905)
		{
			f += 0.001;
		}

		sum += gg[i];

	}

	sum /= 1000;
	printf("rate:%f,index:%f\n", f, sum);
	return 0;

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值