在spyder进行的遗传算法练习

这是一段基于遗传算法框架求解 Rastrigin 函数最小值的 Python 代码,包含目标函数定义、种群初始化、适应度评估、选择算子定义、交叉算子定义,以及基础迭代寻优流程,:

练习代码如下:

python 复制代码
# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

import numpy as np


def rastrigin(x):
    return 20 + sum(xi**2 - 10*np.cos(2*np.pi*xi) for xi in x)


POP_SIZE = 50
DIM = 3
GENERATIONS = 100
VAR_RANGE = [-5, 5]
ELITE_NUM = 1


def initialize_population():
    return np.random.uniform(VAR_RANGE[0], VAR_RANGE[1], (POP_SIZE, DIM))


population = initialize_population()
print(population)

best_individual = None
best_fitness = float('inf')

for gen in range(GENERATIONS):
    fitness = np.array([rastrigin(ind) for ind in population])
    current_best_idx = np.argmin(fitness)
    if fitness[current_best_idx] < best_fitness:
        best_fitness = fitness[current_best_idx]
        best_individual = population[current_best_idx].copy()


def tournament_selection(fitness, k=3):
    selected = []
    for _ in range(POP_SIZE - ELITE_NUM):
        candidates = np.random.choice(len(fitness), k, replace=False)
        winner = candidates[np.argmin(fitness[candidates])]

        selected.append(winner)
    return selected


def sbx_crossover(parent1, parent2, eta=20):
    child1, child2 = parent1.copy(), parent2.copy()
    for i in range(len(parent1)):
        if np.random.rand() < 0.5:
            u = np.random.rand()
            if u <= 0.5:
                beta = (2*u)**(1/(eta+1))
            else:
                beta = (1/(2*(1-u)))**(1/(eta+1))
            child1[i] = 0.5*((1+beta)*parent1[i] + (1-beta)*parent2[i])
            child2[i] = 0.5*((1-beta)*parent1[i] + (1+beta)*parent2[i])
    child1 = np.clip(child1, VAR_RANGE[0], VAR_RANGE[1])
    child2 = np.clip(child2, VAR_RANGE[0], VAR_RANGE[1])
    return child1, child2


print(f"最优个体: {best_individual}")
print(f"最优适应度: {best_fitness:.4f}")
  • # -*- coding: utf-8 -*-:指定文件编码为 UTF-8,保证中文、特殊符号正常显示;
  • 注释块:Spyder 编辑器自动生成的文件说明,无实际运行功能;
  • import numpy as np:导入数值计算库 NumPy,并重命名为np,用于数组操作、随机数生成、数学计算。
  • 功能:定义遗传算法的优化目标函数(多峰测试函数,用于验证优化算法性能);
python 复制代码
def rastrigin(x):
    return 20 + sum(xi**2 - 10*np.cos(2*np.pi*xi) for xi in x)
  • 输入x为一维数组 / 列表,代表优化变量(维度为 DIM);
  • 数学公式,其中,A=10,n=3;
  • 特性 :函数理论最小值为 0,最优解为x=[0,0,0],具有大量局部最优解,是经典的优化测试函数。
python 复制代码
POP_SIZE = 50       # 种群规模:每一代包含50个个体
DIM = 3             # 变量维度:优化3个决策变量
GENERATIONS = 100   # 迭代次数:算法进化100代
VAR_RANGE = [-5, 5] # 变量范围:所有决策变量取值限制在[-5,5]
ELITE_NUM = 1       # 精英个体数量:每一代保留1个最优个体

所有参数为全局常量,控制遗传算法的核心运行规则。

python 复制代码
def initialize_population():
    return np.random.uniform(VAR_RANGE[0], VAR_RANGE[1], (POP_SIZE, DIM))
  • 功能:生成初始种群,为算法提供起始搜索点;
  • 实现 :调用np.random.uniform在[−5,5]范围内生成50 行 3 列的二维数组;
  • 含义:每一行代表 1 个个体(3 维决策变量),共 50 个个体组成初始种群。
python 复制代码
population = initialize_population()  # 生成初始种群
print(population)                     # 打印初始种群所有个体

best_individual = None                # 存储全局最优个体
best_fitness = float('inf')           # 存储全局最优适应度,初始化为无穷大
  • population:存储每一代的所有个体,是算法的核心载体;
  • best_individual:记录迭代过程中找到的最优解;
  • best_fitness:记录最优解对应的函数值,最小化问题初始值设为无穷大。
python 复制代码
for gen in range(GENERATIONS):
    # 计算种群中所有个体的适应度(目标函数值)
    fitness = np.array([rastrigin(ind) for ind in population])
    # 找到当前代适应度最小的个体索引
    current_best_idx = np.argmin(fitness)
    # 更新全局最优解:当前最优 < 历史最优时替换
    if fitness[current_best_idx] < best_fitness:
        best_fitness = fitness[current_best_idx]
        best_individual = population[current_best_idx].copy()
  • 循环:迭代 100 代,完成种群的适应度评估与最优解更新;
  • 适应度计算:遍历种群每个个体,代入 Rastrigin 函数得到适应度值(值越小,个体越优);
  • 最优个体筛选np.argmin(fitness)找到当代最优个体;
  • 全局更新:对比历史最优,保留更优的个体与适应度。
python 复制代码
def tournament_selection(fitness, k=3):
    selected = []
    # 选择数量:种群规模 - 精英数量
    for _ in range(POP_SIZE - ELITE_NUM):
        # 随机无重复抽取3个候选个体
        candidates = np.random.choice(len(fitness), k, replace=False)
        # 候选者中适应度最小的为优胜者
        winner = candidates[np.argmin(fitness[candidates])]
        selected.append(winner)
    return selected
  • 功能 :遗传算法的选择操作,模拟自然界 "优胜劣汰",筛选优质个体用于繁殖;
  • 机制:锦标赛选择(k=3),随机选 3 个个体,保留最优 1 个;
  • 作用:保证优质个体有更高概率被选中,提升算法寻优能力。
python 复制代码
def sbx_crossover(parent1, parent2, eta=20):
    child1, child2 = parent1.copy(), parent2.copy()
    # 逐维度进行交叉操作
    for i in range(len(parent1)):
        if np.random.rand() < 0.5:
            u = np.random.rand()  # 生成0~1随机数
            # 计算交叉系数beta
            if u <= 0.5:
                beta = (2*u)**(1/(eta+1))
            else:
                beta = (1/(2*(1-u)))**(1/(eta+1))
            # 生成两个子代个体
            child1[i] = 0.5*((1+beta)*parent1[i] + (1-beta)*parent2[i])
            child2[i] = 0.5*((1-beta)*parent1[i] + (1+beta)*parent2[i])
    # 限制子代变量在[-5,5]范围内
    child1 = np.clip(child1, VAR_RANGE[0], VAR_RANGE[1])
    child2 = np.clip(child2, VAR_RANGE[0], VAR_RANGE[1])
    return child1, child2
  • 功能 :遗传算法的交叉操作,两个父代个体结合生成子代,实现信息交换;
  • SBX 算子:模拟二进制编码的交叉特性,适用于实数编码种群;
  • eta:分布指数,控制子代与父代的接近程度;
  • np.clip:边界限制,保证子代个体不超出预设变量范围;
  • 输出:返回两个新的子代个体。

还有一小部分未完善,如果有大佬完善了可以发我,我追加链接在文章后面。

运行测试结果:

相关推荐
Gene_20228 小时前
轮式底盘的微分平坦
算法
Vallelonga8 小时前
Rust 从结构体中取字段的引用
开发语言·rust
社交怪人9 小时前
【球体体积】信息学奥赛一本通C语言解法(题号1030)
c语言·开发语言
froginwe119 小时前
Foundation 顶部导航栏详解
开发语言
沐知全栈开发9 小时前
MySQL 运算符详解
开发语言
java修仙传9 小时前
Java 实习日记:断面分析基态限额为空问题的排查与修复
java·开发语言·bug·实习
吴佳浩9 小时前
现代多模态大模型的核心基础:Unified Self-Attention
人工智能·算法·llm
njsgcs9 小时前
我仓库内cad python 有哪些应用到聚类的方法
开发语言·python·聚类