遗传算法低维单目标函数优化

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期

遗传算法详解与实验