模拟退火算法与遗传算法求解多目标优化问题的算法实现(数学建模)

news2024/11/27 10:35:25

一、模拟退火算法

模拟退火算法是一种全局优化算法,解决的问题通常是找到一个最小化(或最大化)某个函数的全局最优解。它通过模拟物理退火的过程来搜索解空间,在开始时以一定的温度随机生成初始解,然后一步步降低温度,同时在当前解的周围随机搜索新的解,并根据一定概率接受更差的解,从而有可能跳出局部最优解,最终得到全局最优解。

下面我们来看一个简单的示例,假设要求解目标函数 f(x,y)=sin⁡(10x)+cos⁡(3y)的全局最小值,取 −2≤x≤2,−1≤y≤1 作为搜索范围。我们可以使用以下代码来实现:

import math
import random

# 定义目标函数
def objective_function(x, y):
    return math.sin(10*x) + math.cos(3*y)

# 定义模拟退火算法
def simulated_annealing(initial_temperature, cooling_rate, num_iterations):
    # 设置初始解和初始温度
    current_solution = [random.uniform(-2, 2), random.uniform(-1, 1)]
    current_energy = objective_function(current_solution[0], current_solution[1])
    current_temperature = initial_temperature

    # 迭代固定次数
    for i in range(num_iterations):
        # 根据当前温度随机生成新的解
        new_solution = [current_solution[0] + 0.1*random.uniform(-1, 1),
                        current_solution[1] + 0.1*random.uniform(-1, 1)]
        new_energy = objective_function(new_solution[0], new_solution[1])

        # 计算能量差
        delta_energy = new_energy - current_energy

        # 如果新解更优,则接受它
        if delta_energy < 0:
            current_solution = new_solution
            current_energy = new_energy
        # 否则以一定概率接受更差的解
        else:
            probability = math.exp(-delta_energy / current_temperature)
            if random.uniform(0, 1) < probability:
                current_solution = new_solution
                current_energy = new_energy

        # 降低温度
        current_temperature *= cooling_rate

    return current_solution, current_energy

# 设置初始温度、冷却速率和迭代次数
initial_temperature = 100
cooling_rate = 0.95
num_iterations = 1000

# 运行模拟退火算法
best_solution, best_energy = simulated_annealing(initial_temperature, cooling_rate, num_iterations)

# 输出结果
print("全局最优解:", best_solution)
print("全局最优值:", best_energy)

在这个示例中,我们使用了 objective_function 函数来定义目标函数。然后定义了 simulated_annealing 函数来实现模拟退火算法的核心部分,其中参数 initial_temperature 代表初始温度、cooling_rate 代表每迭代一次温度降低的比率、num_iterations 代表迭代次数。在 simulated_annealing 函数中,我们使用了当前温度和能量差来决定是否接受新的解,以及在新解较差时是否接受,这些都是模拟退火算法的核心步骤。

最后,我们设置了初始温度、冷却速率和迭代次数,并调用 simulated_annealing 函数运行模拟退火算法,得到了全局最优解和最优值,并将它们输出到控制台上。可以通过多次运行调整参数,得到更精确的结果。

二、遗传算法

如果有多个目标函数,可以使用多目标函数优化算法。其中一个比较常用的算法是 NSGA-II(Non-dominated Sorting Genetic Algorithm II),它是一种利用遗传算法求解多目标优化问题的算法。

NSGA-II 算法的核心思想是通过维护一个帕累托前沿面来寻找非支配解,然后对这些解进行选择和交叉操作,生成下一代种群。具体的步骤如下:

  1. 初始化种群,并计算每个个体的适应度值以及帕累托等级和拥挤距离。
  2. 进行帕累托排序,将种群中所有个体按照帕累托等级从小到大排序,相同等级的个体再按照拥挤距离从大到小排序。
  3. 选择一部分高质量的个体作为父代,并进行交叉和变异操作,生成下一代种群。
  4. 重复以上步骤,直到满足停止条件。

下面是一个使用 Python 实现 NSGA-II 算法解决多目标问题的示例代码:

import random
import copy

# 定义目标函数
def objective_function(population):
    fitness = []
    for x in population:
        obj_1 = pow(x[0], 2)
        obj_2 = pow(x[0]-2, 2) + pow(x[1], 2)
        # 将两个目标函数值合并成一个列表
        fitness.append([obj_1, obj_2])
    return fitness

# 定义帕累托排序
def pareto_ranking(fitness):
    n = len(fitness)
    p = []
    rank = [0] * n
    S = [[] for i in range(n)]
    F = [[] for i in range(n+1)]
    for i in range(n):
        S[i] = []
        rank[i] = 0
        for j in range(n):
            if i != j:
                if fitness[i][0] <= fitness[j][0] and fitness[i][1] <= fitness[j][1]:
                    if j not in S[i]:
                        S[i].append(j)
                elif fitness[j][0] <= fitness[i][0] and fitness[j][1] <= fitness[i][1]:
                    rank[i] += 1
        if rank[i] == 0:
            F[0].append(i)
    i = 0
    while len(F[i]) > 0:
        Q = []
        for j in range(len(F[i])):
            p_j = F[i][j]
            for k in range(len(S[p_j])):
                q = S[p_j][k]
                rank[q] -= 1
                if rank[q] == 0:
                    Q.append(q)
        i += 1
        F[i] = copy.deepcopy(Q)
    del F[len(F)-1]
    for f in F:
        for x in f:
            p.append(x)
    return p

# 定义拥挤距离
def crowding_distance(fitness, indices):
    n = len(indices)
    distance = [0.0] * n
    for m in range(2):
        sorted_indices = sorted(indices, key=lambda x:fitness[x][m])
        distance[sorted_indices[0]] = float('inf')
        distance[sorted_indices[n-1]] = float('inf')
        for i in range(1, n-1):
            distance[sorted_indices[i]] += (fitness[sorted_indices[i+1]][m] - fitness[sorted_indices[i-1]][m])
    return distance

# 定义选择操作
def selection(population, fitness, num_parents):
    parents = []
    n = len(population)
    indices = [i for i in range(n)]
    for i in range(num_parents):
        front = pareto_ranking(fitness)
        distance = crowding_distance(fitness, front)
        max_distance_index = indices[front[distance.index(max(distance))]]
        parents.append(population[max_distance_index])
        indices.remove(max_distance_index)
    return parents

# 定义交叉和变异操作
def crossover(parents, offspring_size):
    offspring = []
    for i in range(offspring_size):
        parent_1 = random.choice(parents)
        parent_2 = random.choice(parents)
        child = [parent_1[j] if random.random() < 0.5 else parent_2[j]
                 for j in range(len(parent_1))]
        offspring.append(child)
    return offspring

def mutation(offspring_crossover):
    for i in range(len(offspring_crossover)):
        if random.random() < 0.1:
            offspring_crossover[i][0] += random.uniform(-0.5, 0.5)
        if random.random() < 0.1:
            offspring_crossover[i][1] += random.uniform(-0.5, 0.5)
    return offspring_crossover

# 设置算法参数
num_generations = 50
population_size = 100
num_parents = 20
offspring_size = population_size - num_parents

# 初始化种群
population = [[random.uniform(-5, 5), random.uniform(-5, 5)] for i in range(population_size)]
for i in range(num_generations):
    # 计算适应度值和帕累托等级
    fitness = objective_function(population)
    # 选择操作
    parents = selection(population, fitness, num_parents)
    # 交叉操作
    offspring_crossover = crossover(parents, offspring_size)
    # 变异操作
    offspring_mutation = mutation(offspring_crossover)
    # 将父代和后代合并成一个种群
    population = parents + offspring_mutation
    # 输出当前最优解
    best_individual_index = pareto_ranking(fitness)[0]
    print("Generation ", i+1, ": Most optimal solution is ", population[best_individual_index])

# 输出所有 Pareto 最优解
pareto_front = pareto_ranking(fitness)
print("\nPareto front:")
for i in pareto_front:
    print(population[i], objective_function([population[i]])[0])

在这个示例中,我们仍然使用 Python 来实现带有两个目标函数的多目标问题。首先定义了 objective_function 函数,它接收一个种群并返回每个个体的两个目标函数值。然后定义了 pareto_ranking 函数和 crowding_distance 函数来计算帕累托等级和拥挤距离。其中,pareto_ranking 函数用来对种群进行帕累托排序,得到每个个体的帕累托等级,crowding_distance 函数用来计算每个个体的拥挤距离。最后,定义了 selection 函数、crossover 函数和 mutation 函数来执行选择、交叉和变异操作,这些操作都是遗传算法的常见操作。

在主函数中,我们使用以上函数实现了 NSGA-II 算法,并使用种群的 Pareto 前沿面来输出所有的可行解。可以通过修改参数,例如种群大小、迭代次数等,来调整算法。

三、区别与联系

模拟退火算法(Simulated Annealing,SA)和 NSGA-II 遗传算法(Non-dominated Sorting Genetic Algorithm II)是两种不同的优化算法,它们具有以下几个区别:

  1. 算法思想不同

    SA 算法是一种启发式随机搜索算法,基于模拟固体物质的退火过程,可以在接受劣解的概率下逐渐接近全局最优解。NSGA-II 算法是一种多目标遗传算法,主要针对多目标优化问题,通过维护帕累托前沿面来寻找非支配解。

  2. 应用场景不同

    SA 算法适用于寻求单目标优化问题的全局最优解,尤其在搜索空间较小或者不存在明显的解析解时比较适用。NSGA-II 算法针对多目标优化问题,可以同时处理多个目标函数并生成 Pareto 前沿面上的一系列 Pareto 最优解。

  3. 优化方法不同

    SA 算法通过改变温度来达到控制接受劣解的概率的目的,同时允许跳出局部最优解,从而在全局范围内搜索解空间。NSGA-II 算法主要通过选择、交叉和变异等操作来生成下一代种群,并通过帕累托排序来维护 Pareto 最优解。

  4. 算法复杂度不同

    SA 算法的时间复杂度与温度下降速率有关,复杂度通常较低,但可能需要进行大量迭代才能收敛到全局最优解。NSGA-II 算法的时间复杂度主要受到种群大小、生成下一代种群的操作等因素的影响,通常情况下比 SA 算法更复杂。

总的来说,模拟退火算法和 NSGA-II 遗传算法都是比较常见的优化算法,其适用的问题类型和搜索策略等方面有所不同,可以根据具体情况选择合适的算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/474984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏

画笔Graphics Java中提供了Graphics类&#xff0c;他是一个抽象的画笔&#xff0c;可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图。 Graphics常用的画图方法如下&#xff1a; drawLine(): 绘制直线drawString(): 绘制字符串drawRect(): 绘制矩形drawRoundRect(): 绘制…

YOLOv8——CV界的XGBoost

yolov8是ultralytics公司于2023年1月开源的anchor-free的最新目标检测算法框架。 封装在ultralytics这个库中&#xff1a;https://github.com/ultralytics/ultralytics 它具有以下优点&#xff1a; 1&#xff0c;性能速度领先&#xff1a;借鉴了之前许多YOLO版本的trick&#x…

spring常用的事务传播行为

事务传播行为介绍 Spring中的7个事务传播行为: 事务行为 说明 PROPAGATION_REQUIRED 支持当前事务&#xff0c;假设当前没有事务。就新建一个事务 PROPAGATION_SUPPORTS 支持当前事务&#xff0c;假设当前没有事务&#xff0c;就以非事务方式运行 PROPAGATION_MANDATORY…

ChatGPT能胜任高级程序员吗?

与开发人员信任的其他软件开发工具不同&#xff0c;AI工具在训练、构建、托管和使用方式等方面都存在一些独特的风险。 自2022年底ChatGPT发布以来&#xff0c;互联网上便充斥着对其几乎相同比例的支持和怀疑的论调。不管你是否喜欢它&#xff0c;AI正在逐步进入你的开发组织。…

JAVA ssm客户信息管理系统idea开发mysql数据库web结构计算机java编程springMVC

一、源码特点 idea ssm客户信息管理系统是一套完善的web设计系统mysql数据库springMVC框架mybatis&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开 发。 java ssm客户信息管理系统idea开发mysql数据…

【五一创作】 SAAS-HRM系统概述与搭建环境

SAAS-HRM系统概述与搭建环境 学习目标&#xff1a; 理解SaaS的基本概念 了解SAAS-HRM的基本需求和开发方式掌握Power Designer的用例图 完成SAAS-HRM父模块及公共模块的环境搭建完成企业微服务中企业CRUD功能 初识SaaS 云服务的三种模式 IaaS&#xff08;基础设施即服务…

业务维度digest日志的记录与监控方案

需求 ​   为了满足从业务整体的维度 实现监控和链路复原&#xff0c;我们希望对于一个业务接口&#xff0c;记录一行请求日志&#xff0c;并通过某个 Unique Id&#xff08;如UserId、OrderId&#xff09;将多行日志关联起来&#xff0c;最终产出一批和业务强相关的数据&am…

软件维护(Software maintenance)的流程

软件维护(Software maintenance)是一个软件工程名词&#xff0c;是指在软件产品发布后&#xff0c;因修正错误、提升性能或其他属性而进行的软件修改。 软件维护主要根据需求变化或硬件环境的变化对应用程序进行部分或全部的修改&#xff0c;修改时应充分利用源程序。修改后要填…

2023年的深度学习入门指南(10) - 前端同学如何进行chatgpt开发

2023年的深度学习入门指南(10) - 前端同学如何进行chatgpt开发 在第二篇&#xff0c;我们使用openai的python库封装&#xff0c;搞得它有点像之前学习的PyTorch一样的库。这一节我们专门给它正下名&#xff0c;前端就是字面意义上的前端。 给gpt4写前端 下面我们写一个最土的…

【BeautifulSoup】——05全栈开发——如桃花来

目录索引 介绍&#xff1a;解析库&#xff1a; 安装&#xff1a;pip install BeautifulSoup4pip install lxml 标签选择器&#xff1a;1.string属性&#xff1a;.name属性&#xff1a;获取标签中的属性值&#xff1a; 实用——标准选择器&#xff1a;使用find_all()根据标签名查…

百城巡展 | 人大金仓4月“双向奔赴”告一段落

人间最美四月天&#xff0c;人大金仓走过上海、宁波、合肥&#xff0c;联合伙伴发布医疗、金融、信息安全、电子档案等多个关键领域的信创联合解决方案&#xff0c;共同为数字基础设施的安全和可持续发展贡献力量&#xff0c;吸引了线上线下近7000人参与。 左右滑动&#xff0c…

大数据架构(一)背景和概念

-系列目录- 大数据架构(一)背景和概念 大数据架构(二)大数据发展史 一、背景 1.岗位现状 大数据在一线互联网已经爆发了好多年&#xff0c;2015年-2020年(国内互联网爆发期)那时候的大数据开发&#xff0c;刚毕业能写Hive SQL配置个离线任务、整个帆软报表都20K起步。如果做到架…

Midjourney 创建私人画图机器人,共享账号如何设置独立绘画服务器(保姆级教程)

你是不是遇到以下问题&#xff1a; 1.Midjourney会员怎么自建绘图服务器&#xff0c;不受其他人的打扰&#xff1f; 2.Midjourney会员共享账号如何自建服务器&#xff0c;供其他人使用&#xff1f; 3.在官方服务器作图&#xff0c;频道里面的人太多了&#xff0c;自己的指令…

【五一创作】( 字符串) 409. 最长回文串 ——【Leetcode每日一题】

❓ 409. 最长回文串 难度&#xff1a;简单 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的回文串 。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。 示例 1: 输入:s “abccccdd”…

时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)

时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比) 目录 时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-GRU、GRU麻雀算法…

第十四章 移动和旋转(下)

本章节我们介绍另外两种形式的旋转&#xff0c;也对应了两个方法。首先是RotateAround方法&#xff0c;他是围绕穿过世界坐标中的 point 点的 axis轴旋转 angle 度。这个方法虽然比较晦涩难懂&#xff0c;但是我们使用一个案例&#xff0c;大家就非常明白了。我们创建一个新的“…

JDBC详解(三):使用PreparedStatement实现CRUD操作(超详解)

JDBC详解&#xff08;三&#xff09;&#xff1a;使用PreparedStatement实现CRUD操作&#xff08;超详解&#xff09; 前言一、操作和访问数据库二、使用Statement操作数据表的弊端三、PreparedStatement的使用1、PreparedStatement介绍2、PreparedStatement vs Statement3、Ja…

连接分析工具箱 | 利用CATO进行结构和功能连接重建

导读 本研究描述了一个连接分析工具箱(CATO)&#xff0c;用于基于扩散加权成像(DWI)和静息态功能磁共振成像(rs-fMRI)数据来重建大脑结构和功能连接。CATO是一个多模态软件包&#xff0c;使研究人员能够运行从MRI数据到结构和功能连接组图的端到端重建&#xff0c;定制其分析并…

牛郎织女

我写的十二星座十二人大多是奇女子&#xff0c;如双子的刘若英《若》、天秤的叶倩文《AB天秤座&#xff0c;Sally》、射手的桂纶镁《半人马座&#xff0c;桂纶镁》、水瓶的杨千嬅《可惜我是水瓶座》、双鱼的安妮伊能静《十二星座十二人之&#xff1a;双鱼&#xff0c;伊能&…

使用cube studio开发机器学习建模的pipeline

&#xff08;作者&#xff1a;陈玓玏&#xff09; Cube Studio目前包含了传统机器学习模板&#xff0c;400AI模型&#xff0c;欢迎私信了解哇&#xff01; 在使用cube studio进行模型训练或推理的过程中&#xff0c;我们有时会发现没有符合自己要求的模板&#xff0c;此时我们…