前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ 手搓遗传算法

C++ 手搓遗传算法

作者头像
用户6021899
发布2024-02-22 08:16:08
1530
发布2024-02-22 08:16:08
举报
文章被收录于专栏:Python编程 pyqt matplotlib

关于遗传算法的介绍请参考下面知乎的链接。

如何通俗易懂地解释遗传算法?有什么例子?- 知乎 (zhihu.com)

遗传算法 - 知乎 (zhihu.com)

下面是我根据遗传算法思想写的求解上图最优值问题的C++源码:

代码语言:javascript
复制
// my 1st 遗传算法
#include <math.h>
#include <array>
#include<vector>
#include <random>
#include <iostream>

using std::array, std::cout, std::endl, std::vector;


// 每个个体用 M * N个元素,元素值为0或1的数组表示
constexpr int M = 4;// 个体染色体数
constexpr int N = 4; //每个染色体上的基因点位数
constexpr int Qty = 100;// 种群大小
constexpr double reserve_rate = 0.05;//精英保留率
constexpr double elamilation_rate = 0.4;//末位淘汰率




// x 定义域(搜索范围)
constexpr double LSL = 0.0;
constexpr double USL = 9.0;

double f(double x) 
{
    return x + 10 * sin(5 * x) + 7 * cos(4 * x);
}



array<array<int, N>, M> generate_rand_individuality()
{
    std::random_device rd;
    std::default_random_engine eng(rd());
    std::uniform_int_distribution<int> distr(0, 1);//生成0到1的之间的平均分布的随机整数
    array<array<int, N>, M> I{};
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            I[i][j] = distr(eng);
        }
    }
    return I;
}



void print_individuality(array<array<int, N>, M> I)
{
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N - 1; j++)
        {
            cout << I[i][j] << ',';
        }
        cout << I[i][N - 1] << '\n';
    }
    cout << endl;
}



double decode(const array<array<int, N>, M> & I)
{
    double result = LSL;
    double Max_number = pow(2, M * N) - 1;
    double sum = 0.0;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            sum += I[i][j] * pow(2, i * N + j);
        }
    }
    result += (USL - LSL) * sum / Max_number;
    return result;
}


double assess(const array<array<int, N>, M> & I)
{
    return f(decode(I));
}



array<array<int, N>, M> reproduce(const array<array<int, N>, M>& I1, const array<array<int, N>, M>& I2)
{
    std::random_device rd;
    std::default_random_engine eng(rd());
    std::uniform_int_distribution<int> distr(0, 1);//生成0到1的之间的平均分布的随机整数
    array<array<int, N>, M> I{};
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            if (I1[i][j] == I2[i][j]) I[i][j] = I1[i][j];
            else I[i][j] = distr(eng);
        }
    }
    return I;
}


struct Grater
{
    bool operator()(const array<array<int, N>, M>& I1, const array<array<int, N>, M>& I2)
{
        return assess(I1) > assess(I2);
    }
};



vector<array<array<int, N>, M>> regroup(const vector<array<array<int, N>, M>>& group)
{ 
    int top_qty    = static_cast<int> (reserve_rate     * Qty);
    int bottom_qty = static_cast<int> (elamilation_rate * Qty);
    vector<array<array<int, N>, M>> new_group{ group };


    int i = top_qty;
    for (int j = 0; j < Qty - bottom_qty; j+=2)
    {
        //除去淘汰的个体外,每两个个体强强结合,生两个仔...
        new_group[i] = reproduce(group[j], group[j+1]);
        new_group[i+1] = reproduce(group[j], group[j + 1]);
        i += 2;
    }
    //淘汰的个体用随机产生的个体替代掉
    for (int i = Qty - bottom_qty; i < Qty; i++)
    {
        new_group[i] = generate_rand_individuality();
    }
    return new_group;
}




int main()
{
    //std::cout << f(7.0) << '\n';
    //std::random_device rd;
    //std::default_random_engine eng(rd());
    //std::uniform_int_distribution<int> distr(0, 1);
    //array<array<int, N>, M> a{ generate_rand_individuality() };
    //array<array<int, N>, M> b{ generate_rand_individuality() };
    //array<array<int, N>, M> c{};
    //c = reproduce(a, b);
    ////array<array<int, N>, M> b{ 1,0,0,0 };
    //print_individuality(a);
    //cout << assess(a) << endl;


    //print_individuality(b);
    //cout << assess(b) << endl;


    //print_individuality(c);
    //cout << assess(c) << endl;


    vector<array<array<int, N>, M>> group{};
    for (int i = 0; i < Qty; i++)
    {
        group.push_back(generate_rand_individuality());
    }


    std::sort(group.begin(), group.end(), Grater());


    //  打印初代评分
    cout << "初代评分:" << endl;
    for (auto &I : group)
    {
        cout << assess(I) << ", ";
    }


    cout << endl;
    cout << endl;


    //迭代
    cout << "每代的第一名的得分:" << endl;
    for(int i =0; i<100; i++)
        {
            group = regroup(group);
            std::sort(group.begin(), group.end(), Grater());
            cout << assess(group.at(0))<<"-> ";
        }
    cout << endl;
    cout << endl;


    //  打印迭代完成后的评分
    cout << "迭代完成后的评分:" << endl;
    for (auto& I : group)
    {
        cout << assess(I) << ", ";
    }
    cout << endl;
    cout <<"迭代完成后的最优基因是" << endl;
    print_individuality(group.at(0));//打印最优基因
    double x = decode(group.at(0));
    cout << "求得的x的值是" << x << endl;
    cout << "此时 x 对应的函数值是" << f(x) << endl;
}

从上图可以看出,19次迭代后已经收敛。

下图是控制台的输出

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档