优化算法——遗传算法(c++)

本文介绍了遗传算法的基本原理和在单目标优化中的应用,包括个体结构、适应值计算、种群初始化、选择、交叉和变异等步骤。同时,详细阐述了NSGA-Ⅱ多目标优化算法的非支配排序和种群选择策略。在代码实现部分,讲解了动态数组、随机数生成、概率选择等关键函数,并提供了单目标和多目标遗传算法的C++实现细节。
摘要由CSDN通过智能技术生成

目录

一、基本介绍

1、遗传算法(单目标)

2、NSGA-Ⅱ(多目标)

二、代码实现

1、常用函数

(1)动态数组 

(2)产生随机数

(3)以概率选择

 (4)for新用法

2、单目标实现

(1)结构体个体

(2)适应值

(3)随机初始化种群

(4)选择

(i)概率选择 o(n)

(ii)竞争选择 o(cn)

(iii)排序选择 o(nlgn)

(5)交叉

(6)变异

(7)完整代码

3、多目标实现

(1)非支配排序

(i)准确计算rank o(n^2)

(ii)随机竞争,淘汰被支配者  o(n)

 (iii)其他选择过程操作

 三、总结


一、基本介绍

1、遗传算法(单目标)

                类似达尔文的进化理论,在生存压力下,种群中具有优势基因的个体更容易存活下去,并产生后代。

                将最终目标设计为生存压力,在一定目标取向下,整体向更优的趋势演化。个体为一次的结果,个体基因为具体方案,通过染色体复制,基因重组和基因变异,产生可能存在的更优势个体。

2、NSGA-Ⅱ(多目标)

                用非对称排序取代单目标的生存压力。首先,支配的含义是目前在二维坐标中有 A 点和 B 点两个不重合的点,仅当 XA<XB且 15 YA<YB时,称 A 支配 B,反之称 B 支配 A。其余情况称互不支配。 其次,互不支配的所有个体组成 Pareto 集,最优的 Pareto 集为其解集内个体不被其他所 有个体支配,称为 Pareto 最优解,标记为 RANK1,只被 RANK1 支配而不被其他个体 支配的 Pareto 集标记为 RANK2,以此类推能将所有个体按 RANK 等级排序,该排序过 程为非支配排序。 NSGA-Ⅱ为在遗传算法的基础上适应度评估以非支配排序的 RANK 等级为评估标准, RANK 越小,生存压力越小。

二、代码实现

1、常用函数

(1)动态数组 

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers;  // 创建一个整数类型的向量

    // 添加元素到向量末尾
    numbers.push_back(10);
    numbers.push_back(20);
    numbers.push_back(30);

    // 获取向量的大小(元素个数)
    size_t size = numbers.size();

    // 访问向量中的元素
    int first_element = numbers[0];  // 使用下标访问
    int last_element = numbers.back();  // 获取末尾元素

    // 修改向量中的元素
    numbers[1] = 25;  // 修改第二个元素

    // 删除向量末尾的元素
    numbers.pop_back();

    // 插入元素到指定位置
    numbers.insert(numbers.begin() + 1, 15);  // 在第二个位置插入元素

    // 删除指定位置的元素
    numbers.erase(numbers.begin() + 2);  // 删除第三个元素

    // 清空向量中的所有元素
    numbers.clear();

    // 判断向量是否为空
    bool is_empty = numbers.empty();

    return 0;
}

(2)产生随机数

int

int rand(int min,int max)//生成[min,max]随机数 
{
    int randomValue;
    randomValue = (rand() % (max - min + 1)) + min;//范围[min,max]
    return randomValue;	
}
int main()
{
    srand(time(0));
    int a=rand(,);
}

int->double

wei=10000.0;			//保留位数 
		maxx=1.0;  				//最大值范围 
		suan=maxx*wei; 
		cr=rand(0,suan)/wei;
		cy=rand(0,suan)/wei;
		cb=rand(0,suan)/wei;

double

#include <iostream>
#include <random>
using namespace std;

int main() {
    

    random_device rd;
    mt19937 gen(rd());
    uniform_real_distribution<> dis(-1.0, 1.0);

    for (int i = 0; i < 10; ++i) {
        double random_value = dis(gen);
        cout << random_value << " ";
    }

    return 0;
}

random_device        初始化随机数生成器

random_device rd;         生成随机数的函数为(命名为)rd

mt19937         是 Mersenne Twister 19937 伪随机数生成器的一个实现,它是 C++ 标准库中的一个类模板。Mersenne Twister 是一种高质量的伪随机数生成器,其主要特点是周期长且随机性较好,适用于多种随机数生成需求。

mt19937 gen(rd());        使gen产生随机数

uniform_real_distribution<>          是 C++ 标准库中的一个随机数分布类,用于生成指定范围内均匀分布的随机实数。它的作用是将伪随机数生成器产生的随机整数转换为指定范围内的随机实数。

uniform_real_distribution<> dis(min, max);           使dis产生min到max的随机实数

调用:double random_value = dis(gen);

(3)以概率选择

#include <iostream>
#include <random>
#include <vector>
using namespace std;

int main() {

    vector<double> probabilities = {0.1, 0.3, 0.6};  // 每个事件的概率

    random_device rd;
    mt19937 gen(rd());
    discrete_distribution<> distribution(probabilities.begin(), probabilities.end());

    for (int i = 0; i < 10; ++i) {
        int random_index = distribution(gen);  // 根据概率分布生成随机整数索引
        cout << "Selected index: " << random_index << endl;
    }

    return 0;
}

 discrete_distribution        这个分布类的构造函数可以接受一个容器,其中存储了每个事件或状态的概率。这些概率可以是正数,但它们的总和必须等于 1。 discrete_distribution 会根据probabilities中的概率生成整数值,使得概率较高的事件更有可能被选中。

调用:int random_index = distribution(gen);

 (4)for新用法

for (数据类型 变量名 : 容器名) {
    // 在这里使用变量名来访问容器中的元素
}
for (double var : individual.variables) {
    // 这里的 var 将依次遍历 individual.variables 中的每个元素
}

for (const 数据类型& 变量名 : 容器名) {
    // 在这里使用变量名来访问容器中的元素
}
for (const vector<int>& front : fronts) {
    // 这里的 front 将依次遍历 fronts 容器中的每个 vector<int> 类型的元素
}

2、单目标实现

(1)结构体个体

struct Individual {
    double value;  // 个体的基因值
    double fitness;  // 个体的适应度值
};

(2)适应值

double fitness_function(double x) {
    return x * x;  // 返回 x 的平方作为适应度函数
}

因目标而定

(3)随机初始化种群

void initialize_population(vector<Individual>& population) {
    random_device rd;  // 创建一个随机设备,用于生成随机种子
    mt19937 gen(rd());  // 创建一个 Mersenne Twister 19937 伪随机数生成器,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值