遗传算法低维单目标函数优化
Posted 图灵奖未来得主
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了遗传算法低维单目标函数优化相关的知识,希望对你有一定的参考价值。
遗传算法低维单目标函数优化
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<algorithm>
using namespace std;
#define SIZE 500 //最大种群个体数
int MAXIMIZATION = 1;//最大化Flag
int MINIMIZATION = 2;//最小化Flag
int Cmax = 100;//适应度值标准最大值
int Cmin = 0;//适应度值标准最小值
constexpr int LENGTH1 = 7;// 第一个变量的染色体长度
constexpr int LENGTH2 = 7;// 第二个变量的染色体长度
constexpr int CHROMLENGTH = LENGTH1 + LENGTH2;// 总染色体长度
int FunctionMode = MAXIMIZATION;//函数类型
constexpr int PopSize = 80;//种群中个体数目
constexpr int MaxGeneration = 45;//停机准则最大代数
double Pc = 0.8;//交叉概率
double Pm = 0.007;//变异概率
//这三个用于记录最坏最好平均数值便于在matlab中画图
double worst1[MaxGeneration + 1];
double average1[MaxGeneration + 1];
double best1[MaxGeneration + 1];
int worst0 = 0, average0 = 0, best0 = 0;
//个体结构体
struct individual {
char chrom[CHROMLENGTH];//染色体
double value; //目标函数值
double fitness; //该个体适应度值
};
bool cmp(individual a, individual b) {
return a.fitness < b.fitness;
}
//全局变量定义
int generation;//当前操作的代数
int best_index;//最好个体的下标
int worst_index;//最坏个体的下标
struct individual bestindividual;//当前代最好的个体
struct individual worstindividual;//当前代最坏的个体
struct individual currentbest;//目前为止最好的个体
struct individual population[SIZE];//种群
//函数声明
void GenerateInitialPopulation(void);
void GenerateNextPopulation(void);
void EvaluatePopulation(void);
long DecodeChromosome(char*, int, int);
void CalculateObjectValue(void);
void CalculateFitnessValue(void);
void FindBestAndWorstIndividual(void);
void PerformEvolution(void);
void SelectionOperator(void);
void CrossoverOperator(void);
void MutationOperator(void);
void OutputTextReport(void);
//主函数
int main(void) {
generation = 0;
GenerateInitialPopulation();//初始化
EvaluatePopulation();//评价
//停机准则generation>=MaxGeneration
while (generation < MaxGeneration) {
generation++;
GenerateNextPopulation();//匹配选择+交叉+变异
EvaluatePopulation();//重新评价
PerformEvolution();//基于精英模型进行进化操作
OutputTextReport();//输出当前代数的结果
}
for (int i = 0; i < MaxGeneration; i++) {
cout << i << ',';
}cout << endl << endl;
for (int i = 0; i < MaxGeneration; i++) {
cout << best1[i] << ',';
}cout << endl << endl;
for (int i = 0; i < MaxGeneration; i++) {
cout << average1[i] << ',';
}cout << endl << endl;
for (int i = 0; i < MaxGeneration; i++) {
cout << worst1[i] << ',';
}cout << endl << endl;
}
//初始化种群,二进制编码改为格雷码编码
void GenerateInitialPopulation(void) {
for (int i = 0; i < PopSize; i++)
for (int j = 0; j < CHROMLENGTH; j++)
population[i].chrom[j] = (rand() % 10 < 5) ? '0' : '1';
//转换为格雷码
for (int i = 0; i < PopSize; i++) {
for (int j = CHROMLENGTH - 1; j > 0; j--) {
if (population[i].chrom[j] != population[i].chrom[j - 1]) {
population[i].chrom[j] = '1';
}
else {
population[i].chrom[j] = '0';
}
}
}
}
void EvaluatePopulation(void) {
CalculateObjectValue();//计算目标函数值
CalculateFitnessValue();//计算适应度值
FindBestAndWorstIndividual();//当前代数最优个体
}
//解码,从population[point]到population[length-1]
long DecodeChromosome(char* string, int point, int length) {
int i;
long decimal = 0;
char* pointer;
for (i = 0, pointer = string + point; i < length; i++, pointer++)
//二进制转化为十进制
decimal += (*pointer - '0') << (length - 1 - i);
return decimal;
}
//计算目标函数值
void CalculateObjectValue(void) {
int i;
long temp1, temp2;
double x1, x2;
//函数
for (i = 0; i < PopSize; i++) {
temp1 = DecodeChromosome(population[i].chrom, 0, LENGTH1);
temp2 = DecodeChromosome(population[i].chrom, LENGTH1, LENGTH2);
/*x1 = 10.24 * temp1 / 1023.0 - 5.12;//解码公式
x2 = 10.24 * temp2 / 1023.0 - 5.12;
population[i].value = x1 * x1 + x2 * x2;*/
//每个算例,为了方便
/* 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);*/
x1 = 12 * temp1 / 1023.0 - 6;//解码公式
x2 = 12 * temp2 / 1023.0 - 6;
population[i].value = (x1*x1+x2-11)* (x1 * x1 + x2 - 11)+(x1+x2*x2-7)* (x1 + x2 * x2 - 7);
}
}
//不同于课堂上直接使用目标函数,本算法对适应度函数进行调整
void CalculateFitnessValue(void) {
int i;
double temp = 0;
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;//value越小,temp越大
else
temp = 0.0;
}
population[i].fitness = temp;
}
}
void FindBestAndWorstIndividual(void) {
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;
}
if (population[i].fitness < worstindividual.fitness) {
worstindividual = population[i];
worst_index = i;
}
sum += population[i].fitness;
}
if (generation == 0) {//第0代,初始化
currentbest = bestindividual;
}
else if (bestindividual.fitness > currentbest.fitness) {
currentbest = bestindividual;
}
best1[best0++] = currentbest.value;
worst1[worst0++] = worstindividual.value;
}
void GenerateNextPopulation(void) {
SelectionOperator();//匹配选择
CrossoverOperator();//交叉操作
MutationOperator();//变异操作
}
//匹配选择
void SelectionOperator(void) {
int i, index;
double p, sum = 0.0;
double cfitness[SIZE]; //累积适应度比例
struct individual newpopulation[SIZE];//新种群
//计算相对适应度
for (i = 0; i < PopSize; i++) {
sum += population[i].fitness;
}
//每个个体按照适应度分配的比例
for (i = 0; i < PopSize; i++)
cfitness[i] = population[i].fitness / sum;
//计算累积适应度比例
for (i = 1; i < PopSize; i++)
cfitness[i] = cfitness[i - 1] + cfitness[i];
//选择操作
for (i = 0; i < PopSize; i++) {
p = rand() % 1000 / 1000.0;//产生PopSize个随机数,下一代还是PopSize个个体
index = 0;
while (p > cfitness[index]) index++;
newpopulation[i] = population[index];//进入繁衍
}
for (i = 0; i < PopSize; i++)
population[i] = newpopulation[i];
}
//交叉操作
void CrossoverOperator(void) {
int i, j, point, point1, point2, maxxx, minnn, temp, index[SIZE];
double p;
char ch;
//随机配对父代
for (i = 0; i < PopSize; i++) {
index[i] = i;
}
//打乱染色体的顺序,随机配对
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) {
point1 = rand() % (CHROMLENGTH - 1) + 1;//随机产生交叉位置
point2 = rand() % (CHROMLENGTH - 1) + 1;
if (point1 <= point2) {
maxxx = point2;
minnn = point1;
}
else {
maxxx = point1;
minnn = point2;
}
for (j = minnn; j < maxxx; 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(void) {
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';
}
}
}
}
//基于精英模型进行进化操作
//目的是一定要把最好的保存下来
//结合(μ,λ)-ES
void PerformEvolution(void) {
if (bestindividual.fitness > currentbest.fitness) {
currentbest = population[best_index];
}
else {
population[worst_index] = currentbest;
}
sort(population, population + PopSize, cmp);
int k = 8;
for (int i = 0; i < k; i++) {
population[i] = population[CHROMLENGTH - i];
}
}
//输出当前代数的结果
void OutputTextReport(void) {
double sum = 0, average = 0;
for (int i = 0; i < PopSize; i++) sum += population[i].value;
average = sum / PopSize;
cout << "gen=" << generation << ",avg=" << average << ", best=," << currentbest.value;
cout << "chromosome=";
average1[average0++] = average;
for (int i = 0; i < CHROMLENGTH; i++) {
cout << currentbest.chrom[i];
}
cout << endl;
}
以上是关于遗传算法低维单目标函数优化的主要内容,如果未能解决你的问题,请参考以下文章
单目标优化求解基于matlab遗传算法求解非线性目标函数最小值问题含Matlab源码 1574期
优化求解基于matlab粒子群与遗传算法混合算法求解切削参数优化问题(以成本和碳排放量为目标函数)含Matlab源码 1619期