遗传算法实现

  听闻遗传算法NB,我就小试了一下,一开始没有设置遗传概率,让每一次迭代都发生变异,效果很不好。后来设置了有概率的变异,发现妙呀。直接上代码啦。

头文件:

InheritanceAlgorithm.h

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <cmath>

using namespace std;

//#define f(x) - (x * x) + 16 * x + 16 // Aim Function
#define f(x) - (x * x) + 6 * x - 1

#define SOLUTION_RANGE 31

#define POPULATION_SIZE 8 // The Size of Population
#define ITERATION_NUM 1000 // iteration 1000 times
#define PROBABILITY_VARIATION 0.1 // The probability of variation

int SOLUTION_RANGE_BINARY_DIGIT = 1;

int group[POPULATION_SIZE][2];

void InitPopulation ();
void CalculateFitness ();
void ChooseNewGroup ();
void Reproduction ();
int BornChild (int father, int mother);
int DecimalToBinary (int decimal);
int BinaryToDecimal (int binary);
int Variation ();

源文件:

 

InheritanceAlgorithm.cc

#include "InheritanceAlgorithm.h"

int main ()
{

    InitPopulation ();
    int TIMES = 0;
    while (TIMES < ITERATION_NUM) {
        CalculateFitness ();
        ChooseNewGroup ();
        Reproduction ();
        Variation ();
        cout << "The " << TIMES << " time : " << endl;
        for (int icount = 0; icount < POPULATION_SIZE; icount++) {
            cout << group[icount][0] << endl;
        }
        TIMES++;
    }
    return 1;
}


void InitPopulation () {
    int total_range = SOLUTION_RANGE;
    while (total_range != 1 && total_range != 0) {
        SOLUTION_RANGE_BINARY_DIGIT += 1;
        total_range /= 2;
    }
    srand (time (NULL));
    for (int icount = 0; icount < POPULATION_SIZE; icount++) {
        group[icount][0] = (int) (rand () % SOLUTION_RANGE);
        group[icount][1] = 0; // Set init fitness is zero
    }
}

void CalculateFitness () {
    for (int icount = 0; icount < POPULATION_SIZE; icount++) {
        group[icount][1] = f(group[icount][0]);
        if (group[icount][1] < 0) {
            group[icount][1] = 0;
        }
    }
}

void ChooseNewGroup () {
    int sumFitness = 0; // Total fitnesses
    for (int icount = 0; icount < POPULATION_SIZE; icount++) {
        sumFitness += group[icount][1];
    }
    if (sumFitness == 0) {
        return;
    }
    double newGroupPro[POPULATION_SIZE]; // pro
    for (int  icount = 0; icount < POPULATION_SIZE; icount++) {
        newGroupPro[icount] = (double) group[icount][1] / sumFitness;
    }
    for (int  icount = 1; icount < POPULATION_SIZE; icount++) {
        newGroupPro[icount] = newGroupPro[icount - 1] + newGroupPro[icount];
    }
    int SAVE_GROUP_NUM[POPULATION_SIZE];
    for (int  icount = 0; icount < POPULATION_SIZE; icount++) {
        double m_rand = rand () / double (RAND_MAX);
        for (int ientry = 0; ientry < POPULATION_SIZE; ientry++) {
            if (newGroupPro[ientry] >= m_rand) {
                SAVE_GROUP_NUM[icount] = ientry;
                break;
            }
        }
        continue;
    }
    int newGroup[POPULATION_SIZE][2];
    for (int  icount = 0; icount < POPULATION_SIZE; icount++) {
        newGroup[icount][0] = group[SAVE_GROUP_NUM[icount]][0];
        newGroup[icount][1] = f(newGroup[icount][0]);
    }
    memcpy (group, newGroup, POPULATION_SIZE * 2 * sizeof (int));
}

void Reproduction () {
    int father_num, mother_num, child;
    father_num = rand () % POPULATION_SIZE;
    mother_num = rand () % POPULATION_SIZE;
    child = BornChild (group[father_num][0], group[mother_num][0]);
    // Though we have a child but it may can not alive, which by its fitness
    int avgFitness = 0, sumFitness = 0;
    for (int icount = 0; icount < POPULATION_SIZE; icount ++) {
        sumFitness += group[icount][1];
    }
    avgFitness = sumFitness / POPULATION_SIZE;
    if (f(child) < avgFitness) { // This child dead
        return;
    } else { // Lucky dog
        int deadNum = rand () % POPULATION_SIZE;
        group[deadNum][0] = child;
        group[deadNum][1] = 0;
    }
}

int BornChild (int father, int mother) {
    int changePoint = pow (10, (rand () % SOLUTION_RANGE_BINARY_DIGIT + 1));
    int father_binary, mother_binary, child_binary;
    int sperm, egg;
    int child;
    father_binary = DecimalToBinary (father);
    mother_binary = DecimalToBinary (mother);
    // Child gets father's first half and mother's bottom half
    sperm = (father_binary / changePoint) * changePoint;
    egg   = mother_binary % changePoint;
    child_binary = sperm + egg;
    child = BinaryToDecimal (child_binary);
    return child;
}

int DecimalToBinary (int decimal) {
    int binary = 0;
    int digit = 1;
    while (decimal != 0) {
        binary += (decimal % 2) * digit;
        decimal /= 2;
        digit *= 10;
    }
    return binary;
}

int BinaryToDecimal (int binary) {
    int index_10 = 10, index_2 = 0;
    int decimal = 0;
    while (binary != 0) {
        decimal += (binary % index_10) * pow (2, index_2);
        index_2 += 1;
        binary /= 10;
    }
    return decimal;
}

int Variation () {
    // My opinion is variation will happen in every time
    if (rand () / double (RAND_MAX) <= PROBABILITY_VARIATION)
    {
    int varistionPosition = rand () % 20;
    int individualPosition = varistionPosition / 5;
    int innerPosition = varistionPosition % 5;
    int varistionIndivdual = group[individualPosition][0];
    int varistionIndivdualBinary = DecimalToBinary (varistionIndivdual);
    int preNum = varistionIndivdualBinary / pow (10, innerPosition + 1);
    int sufNum = varistionIndivdualBinary % (int) pow (10, innerPosition);
    int aimPos = (varistionIndivdualBinary - preNum - sufNum ) / pow (10, innerPosition);
    if (aimPos == 0) {
        aimPos = 1;
    } else {
        aimPos = 0;
    }
    int aimNum = BinaryToDecimal (preNum + sufNum + aimPos * pow (10, innerPosition));
    group[individualPosition][0] = aimNum;
    }
}

以为会很难,发现还好,请多指教!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值