优化算法(寻优问题)

news2025/8/1 15:14:33

前言

  • 群智能算法(全局最优):模拟退火算法(Simulated annealing,SA),遗传算法(Genetic Algorithm, GA),粒子群算法(Particle Swarm Optimization,PSO)
  • 局部搜索算法(local search algorithm):爬山算法 (Hill Climbing),禁忌算法(Tabu Search,TS)
  • 路径搜索算法:A* Search

模拟退火算法

模拟退火算法(Simulate Anneal,SA)是一种通用概率演算法,用来在一个大的搜寻空间内找寻命题的最优解。它是基于Monte-Carlo迭代求解策略的一种随机寻优算法模拟退火算法是解决TSP问题的有效方法之一。

  • 初始温度 T0、降温系数 Δ(0到1之间)、终止温度 Tk
  • (外层循环)降温过程:每次T乘上Δ,直到 T≤Tk
  • (内层循环)概率选择新解:在温度T时,选择领域解进行判断,优解直接接受,对于劣解,概率接受(T 越大时概率越大,新解和旧解差绝对值越小时概率越小)

过程详解

基本要素和具体意义
基本流程图和伪代码

实际案例 - 背包问题

代码

class SimulatedAnnealing(object):
    def __init__(self, weight_list, volume_list, value_list, Weight_threshold_value, Volume_threshold_value, satisfying_value, break_T):
        """背包物体属性"""
        self.object_total_number = len(weight_list)
        self.weight_list = weight_list
        self.volume_list = volume_list
        self.value_list = value_list
        self.Weight_threshold_value = Weight_threshold_value
        self.Volume_threshold_value = Volume_threshold_value
        self.best_value = -1  # 更新最优值
        self.cur_total_weight = 0
        self.cur_total_volume = 0
        self.cur_total_value = 0
        
        self.best_indexs_way = [0] * self.object_total_number
        self.current_indexs_way = [0] * self.object_total_number  # best_way 记录全局最优解方案   now_way 记录当前解方案
        self.weight = self.weight_list
        self.value = self.value_list
        self.volume = self.volume_list

        """跳出条件"""
        self.satisfying_value = satisfying_value
        self.break_T = break_T

        """模拟退火属性"""
        self.T = 200.0  # 温度
        self.af = 0.95  # af退火率
        self.balance = 500  # 平衡次数
        self.iter_times = 100  # 迭代次数

    def initialize(self):

        """初始化,产生随机解"""
        while True:
            for k in range(self.object_total_number):
                if random.random() < 0.5:
                    self.current_indexs_way[k] = 1
                else:
                    self.current_indexs_way[k] = 0
            self.calculate_value(self.current_indexs_way)
            if self.cur_total_weight < self.Weight_threshold_value and self.cur_total_volume < self.Volume_threshold_value:
                break
        self.best_value = self.calculate_value(self.current_indexs_way)
        self.copy_list(self.best_indexs_way, self.current_indexs_way)

    def copy_list(self, a, b):  # 复制函数 把b列表的值赋值a列表
        for i in range(len(a)):
            a[i] = b[i]

    def calculate_value(self, x):
        """计算背包的总重量、总体积、总价值"""
        self.cur_total_weight = 0
        self.cur_total_volume = 0
        self.cur_total_value = 0
        for i in range(self.object_total_number):
            self.cur_total_weight += x[i] * self.weight[i]  # 当前总重量
            self.cur_total_volume += x[i] * self.volume[i]  # 当前总体积
            self.cur_total_value += x[i] * self.value[i]  # 当前总价值
        return self.cur_total_value

    def get_object(self, x):  # 随机将背包中已经存在的物品取出
        while True:
            ob = random.randint(0, self.object_total_number - 1)
            if x[ob] == 1:
                x[ob] = 0
                break

    def put_object(self, x):  # 随机放入背包中不存在的物品
        while True:
            ob = random.randint(0, self.object_total_number - 1)
            if x[ob] == 0:
                x[ob] = 1
                break

    def run(self):
        self.initialize()  # 初始化,产生初始解
        for i in range(self.iter_times):
            test_indexs_way = [0] * self.object_total_number
            now_total_value = 0  # 当前背包价值
            for i in range(self.balance):
                now_total_value = self.calculate_value(self.current_indexs_way)
                self.copy_list(test_indexs_way, self.current_indexs_way)
                ob = random.randint(0, self.object_total_number - 1)  # 随机选取某个物品
                if test_indexs_way[ob] == 1:  # 如果物品在背包中
                    self.put_object(test_indexs_way)  # 随机放入背包中不存在的物品
                    test_indexs_way[ob] = 0  # 在背包中则将其拿出,并加入其它物品
                else:  # 不在背包中则直接加入或替换掉已在背包中的物品
                    if random.random() < 0.5:
                        test_indexs_way[ob] = 1
                    else:
                        self.get_object(test_indexs_way)
                        test_indexs_way[ob] = 1
                temp_total_value = self.calculate_value(test_indexs_way)
                if self.cur_total_weight > self.Weight_threshold_value or self.cur_total_volume > self.Volume_threshold_value:
                    continue  # 非法解则跳过
                if temp_total_value > self.best_value:  # 如果新的解更好,更新全局最优
                    self.best_value = temp_total_value
                    self.copy_list(self.best_indexs_way, test_indexs_way)

                if temp_total_value > now_total_value:  # 如果新的解比当前解更好,直接接受新解
                    self.copy_list(self.current_indexs_way, test_indexs_way)
                else:
                    g = 1.0 * (temp_total_value - now_total_value) / self.T
                    if random.random() < math.exp(g):  # 概率接受劣解
                        self.copy_list(self.current_indexs_way, test_indexs_way)
            self.T = self.T * self.af  # 温度下降

            """跳出条件, 达到满意的解或者温度直接跳出"""
            if self.best_value > self.satisfying_value or self.T < self.break_T:
                break

        # 方案转为索引的形式
        best_object_number = []
        for i in range(object_total_number):
            if self.best_indexs_way[i]:
                best_object_number.append(i)
        print(f"最好的选择方案是取第best_object_number:{best_object_number}个物品,total_value:{self.best_value}")
import random, math
object_total_number=9
weight_list = random.sample(range(1, 100), object_total_number)
volume_list = random.sample(range(1, 100), object_total_number)
value_list = random.sample(range(1, 1000), object_total_number)
Weight_threshold_value = sum(weight_list) / 2  # 取总和值的一半算了?直接不用改动了
Volume_threshold_value = sum(volume_list) / 2
    
print(f"Weight_threshold_value:{Weight_threshold_value}")
print(f"Volume_threshold_value:{Volume_threshold_value}")
print(f"weight_list:{weight_list}")
print(f"volume_list:{volume_list}")
print(f"value_list:{value_list}")
    
satisfying_value = 999999  # 设置满意解,达到就直接退出了
break_T = 1  # 设置跳出温度
SimulatedAnnealing_obj = SimulatedAnnealing(weight_list=weight_list, volume_list=volume_list, value_list=value_list,
                                            Weight_threshold_value=Weight_threshold_value,
                                            Volume_threshold_value=Volume_threshold_value,
                                            satisfying_value=satisfying_value, break_T=break_T)
SimulatedAnnealing_obj.run()

输出结果:

Weight_threshold_value:258.0
Volume_threshold_value:228.0
weight_list:[53, 71, 16, 66, 74, 75, 55, 18, 88]
volume_list:[46, 41, 31, 15, 21, 47, 78, 89, 88]
value_list:[732, 886, 98, 889, 128, 966, 355, 140, 491]
最好的选择方案是取第best_object_number:[1, 2, 3, 5, 7]个物品,total_value:2979

 

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

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

相关文章

前端:你不知道的async await

1.先抛出一个场景&#xff1a;你是否在日常开发中经常使用类似代码&#xff1f;async function getXXList () {const result await this.getArrListApi({page:1,id:2})this.arr result.data.listconsole.log(结果是…, this.arr)……………………其他逻辑代码 }1.1 问题那你是…

OM | 顶刊论文解读:一种求解最大边权团问题的精确算法

解读人&#xff1a;曲晨辉&#xff0c;陈盈鑫&#xff0c;孙楚天&#xff0c;杨李平&#xff0c;张云天 编者按 本次解读的文章是于2020年发表在INFORMS Journal on Computing的“A Lagrangian Bound on the Clique Number and an Exact Algorithm for the Maximum Edge Weigh…

双指针、字符串、哈希表、链表、数组总结

目录总结1、交换元素swap2、链表设置哑结点3、while(cur -> next ! nullptr)代表运行到倒数第二个元素&#xff0c;也就是cur此时为倒数第一个元素4、在cur初始指向哑结点时&#xff0c;下面执行cur指向index的前一个节点5、关于链表&#xff0c;什么移动删除元素等&#xf…

关于用windows开发遇到的各种乌龙事件之node版本管理---nvm install node之后 npm 找不到的问题

友情提醒&#xff0c;开发最好用nvm控制node版本 nrm 控制镜像源&#xff0c;能少掉很多头发开发过程中技术迭代更新的时候最要老命的就是 历史项目的node版本没有记录&#xff0c;导致开启旧项目的时候就会报错。尤其是npm 升级到8.x.x以后&#xff0c;各种版本不兼容。 真…

如何5分钟跑起来一个完整项目?

今天熊哥和大家聊聊&#xff0c;我怎么在5分钟之内生成一个完整的项目。 效果 看看这个面板&#xff0c;这居然是我花了5分钟成功跑起来的项目。 竟然具备超过三十项功能。还可以直接在页面上生成代码。 它是什么&#xff1f;它是 go-gin-api 它支持哪些功能&#xff1f; 可…

【OpenAI】基于 Gym-CarRacing 的自动驾驶练习项目 | 路径训练功能的实现 | GYM-Box2D CarRacing

限时开放&#xff0c;猛戳订阅&#xff01; &#x1f449; 《一起玩蛇》&#x1f40d; &#x1f4ad; 写在前面&#xff1a; 本篇是关于多伦多大学自动驾驶专业项目的博客。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2…

RocketMQ实现延迟队列精确到秒级实现

前言篇&#xff1a;为了节约成本&#xff0c;决定通过自研来改造rocketmq&#xff0c;添加任意时间延迟的延时队列&#xff0c;开源版本的rocketmq只有支持18个等级的延迟时间&#xff0c;其实对于大部分的功能是够用了的&#xff0c;但是以前的项目&#xff0c;全部都是使用了…

剑指 Offer 12. 矩阵中的路径

⭐简单说两句⭐ CSDN个人主页&#xff1a;后端小知识 &#x1f50e;GZH&#xff1a;后端小知识 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; Hello吖&#xff0c;各位小伙伴大家好呀&#xff0c;今天我采用了一种特别的方式&#x1f60e;来…

《关于我找了好久的bug,却没找出来的,又不小心解决了的事》

个人简介 作者简介&#xff1a;大家好&#xff01;我是yukki。个人主页&#xff1a;yukki. 喜欢&#xff1a;&#x1f308;点赞&#x1f308;收藏&#x1f308;一键三连&#xff01;共勉问题&#xff1a; 这是一个SpringBoot问题 刚开始很正常可以启动&#xff0c;但是加了r…

键盘布局持久化技术

**01 **键盘布局简介 键盘布局是按键在键盘上的分布模式&#xff0c;决定了键位顺序。键盘布局在发展过程中&#xff0c;由于使用习惯的不同&#xff0c;各国间使用的键盘布局存在细微差别&#xff0c;因此在Windows系统上以国家为单位区分不同的键盘布局方案。我们最熟悉的布…

后端接收格式为x-www-form-urlencoded的数据

1.x-www-form-urlencoded是什么&#xff1f; x-www-form-urlencoded纸面翻译即所谓url格式的编码&#xff0c;是post的默认Content-Type&#xff0c;其实就是一种编码格式&#xff0c;类似json也是一种编码传输格式。form表单中使用 form的enctype属性为编码方式&#xff0…

【MySQL】5.7版本解压安装配置

前言 之所以使用解压版本&#xff0c;而不使用exe安装&#xff0c;因为exe的安装方式删除过于麻烦&#xff01;&#xff01;&#xff01; 如果安装MySQL过程中&#xff0c;出错了或者想重新在来一把&#xff0c;删除mysql服务即可 sc delete mysql # 删除已经安装好的Mysql&a…

ifconfig不显示ipv4地址,ifconfig eth0 192.168.5.9失败

ifconfig eth0 192.168.5.9设置ip地址后&#xff0c;通过ifconfig仍然没有ipv4地址&#xff1a; 一、 执行ifup eth0启动eth0: ifconfig、ifup、ifdown &#xff1a;这三个命令的用途都是启动网络接口&#xff0c;不过&#xff0c;ifup 与 ifdown 仅就 /etc/sysconfig/network-…

【数据结构】红黑树

红黑树一、红黑树的概念二、红黑树的接口2.1 插入三、验证四、源码一、红黑树的概念 红黑树也是一个二叉搜索树&#xff0c;他是通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;最长路径长度不超过最短路径长度的 2 倍保持近似平衡。他在每个节点添加了一…

华为OD机试题,用 Java 解【勾股数元组】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

骨传导耳机靠谱吗,骨传导耳机的原理是什么

很多人刚开始接触骨传导耳机时都会具有一个疑问&#xff0c;骨传导耳机是不是真的靠谱&#xff0c;是不是真的不伤害听力&#xff1f;骨传导耳机传输声音的原理是什么&#xff1f; 下面就给大家讲解一下骨传导耳机传输声音的原理以及骨传导耳机对听力到底有没有伤害。 骨传导…

Python编写GUI界面,实现小说下载器

嗨害大家好鸭&#xff01;我是小熊猫~思路一、数据来源分析二. 代码实现步骤代码实现一、单章小说下载二、整本小说下载三、多线程采集四、采集排行榜所有小说五、搜索小说功能六、GUI界面<center>**&#x1f447;问题解答 源码获取 技术交流 抱团学习请联系&#x1f…

【蓝桥集训】第七天——并查集

作者&#xff1a;指针不指南吗 专栏&#xff1a;Acwing 蓝桥集训每日一题 &#x1f43e;或许会很慢&#xff0c;但是不可以停下来&#x1f43e; 文章目录1.亲戚2.合并集合3.连通块中点的数量有关并查集的知识学习可以移步至—— 【算法】——并查集1.亲戚 或许你并不知道&#…

华为OD机试题,用 Java 解【喊 7 的次数重排】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

大数据开发 - Java入门2

目录Java基础知识注释关键字常量标识符测试题回顾Java基础知识 注释 对程序的解释说明 分类&#xff1a; 单行注释&#xff1a;// 对本行后面的内容进行注释多行注释&#xff1a;/*解释内容 */文档注释 &#xff1a;/** 注释内容*/ --用于产生帮助文档&#xff0c;也有多行注…