【算法】模拟退火

news2024/9/24 15:23:14

一、引言

        模拟退火算法(Simulated Annealing, SA)是一种启发式搜索算法,它通过模拟物理中的退火过程来解决优化问题。这种算法能够跳出局部最优解,寻找全局最优解,特别适用于解决复杂的优化问题。

二、算法原理

        模拟退火算法的核心原理是模拟物理中的退火过程,将问题的解状态视为物理系统的状态,目标函数值视为系统的能量。算法从初始温度开始,通过随机扰动当前解产生新解,并根据Metropolis准则决定是否接受新解。随着温度的逐渐降低,系统逐渐趋于稳定,最终在低温下达到全局最优或近似最优解。

        模拟退火算法(Simulated Annealing, SA)也是一种基于概率的优化算法,灵感来源于金属退火过程。金属退火是一个加热和缓慢冷却的过程,目的是提高材料的强度和硬度。模拟退火算法试图从一个初始解出发,逐步搜索其他可能解,以找到全局最优解。

其工作原理如下:

  • 随机选择初始解和初始温度。
  • 利用当前温度对解进行扰动,产生新解。
  • 计算新解与旧解的目标函数值:
    • 如果新解更优,则接受新解。
    • 如果新解不优,则以一定概率接受新解(即存在“跳出局部最优”的可能性),概率依赖于当前温度和解的优劣。
  • 随着每次迭代,逐渐降低温度。
  • 直到达到终止条件(如达到最大迭代次数或温度降至某个阈值)。

三、数据结构

模拟退火算法主要涉及以下数据结构:

  • 解空间:表示所有可能解的集合。
  • 当前解:当前迭代中正在考虑的解。
  • 新解:通过随机扰动当前解产生的新解。
  • 温度参数:控制算法搜索过程的冷却速度。

四、算法使用场景

模拟退火算法适用于多种优化问题,包括但不限于:

  • 调度问题:在满足约束条件下,优化任务的执行顺序。
  • 神经网络权重优化:调整神经网络的权重和偏置,以提高模型性能,超参数优化等。
  • 组合优化问题:如旅行商问题(TSP)、背包问题等。

  • N-Queens 问题:寻找 N 皇后问题的解。
  • 约束满足问题:如图着色问题。

五、算法实现

  • 初始化:选择初始解,并设置初始温度。
  • 迭代:在当前解的邻域内生成一个新解。
  • 接受准则:如果新解比当前解好,则接受新解;如果新解较差,则根据概率接受新解(这个概率随着温度的降低而减少)。
  • 降温:逐步降低温度,使得接受较差解的概率逐渐减小。
  • 终止条件:当温度降低到指定值或迭代次数达到上限时,算法停止。

import math
import random

def simulated_annealing(initial_state, temperature, cooling_rate, max_iterations, objective_function):
current_state = initial_state
current_energy = objective_function(current_state)

for i in range(max_iterations):
# 生成新解
new_state = perturb(current_state) # perturb是自定义的新解生成函数
new_energy = objective_function(new_state)

# 计算接受概率
if new_energy < current_energy:
current_state = new_state
current_energy = new_energy
else:
acceptance_probability = math.exp((current_energy - new_energy) / temperature)
if random.random() < acceptance_probability:
current_state = new_state
current_energy = new_energy

# 降温
temperature *= cooling_rate

return current_state

def perturb(state):
# 这里定义扰动操作,比如随机交换两个元素
new_state = state[:] # 复制当前状态
i, j = random.sample(range(len(state)), 2)
new_state[i], new_state[j] = new_state[j], new_state[i]
return new_state

def objective_function(state):
# 计算目标函数值,示例计算归并值
return sum(state)

# 示例使用
initial_state = [5, 3, 1, 7, 2, 4, 6]
temperature = 1000
cooling_rate = 0.95
max_iterations = 1000
best_state = simulated_annealing(initial_state, temperature, cooling_rate, max_iterations, objective_function)
print("Best state:", best_state)
print("Objective value:", objective_function(best_state))

六、其他同类算法对比

  • 遗传算法:基于自然选择和遗传机制,适合大规模复杂的优化问题,相比之下计算开销大。
  • 粒子群优化:通过群体智能进行搜索,适合多维和非线性问题,通常收敛速度较快。
  • 蚁群算法:通过模拟蚂蚁觅食行为进行优化,适合图论中的路径问题。

七、多语言代码实现

Java

import java.util.Random;

public class SimulatedAnnealing {

private static double objectiveFunction(int[] state) {
double sum = 0;
for (int i : state) {
sum += i;
}
return sum;
}

private static int[] perturb(int[] state) {
Random rand = new Random();
int[] newState = state.clone();
int i = rand.nextInt(state.length);
int j = rand.nextInt(state.length);
// 交换元素
int temp = newState[i];
newState[i] = newState[j];
newState[j] = temp;
return newState;
}

public static int[] simulatedAnnealing(int[] initialState, double temperature, double coolingRate, int maxIterations) {
int[] currentState = initialState;
double currentEnergy = objectiveFunction(currentState);

for (int i = 0; i < maxIterations; i++) {

int[] newState = perturb(currentState);
double newEnergy = objectiveFunction(newState);

if (newEnergy < currentEnergy) {
currentState = newState;
currentEnergy = newEnergy;
} else {
double acceptanceProbability = Math.exp((currentEnergy - newEnergy) / temperature);
if (Math.random() < acceptanceProbability) {
currentState = newState;
currentEnergy = newEnergy;
}
}

// 降温
temperature *= coolingRate;
}

return currentState;
}

public static void main(String[] args) {
int[] initialState = {5, 3, 1, 7, 2, 4, 6};
double temperature = 1000.0;
double coolingRate = 0.95;
int maxIterations = 1000;

int[] bestState = simulatedAnnealing(initialState, temperature, coolingRate, maxIterations);
System.out.println("Best state: " + java.util.Arrays.toString(bestState));
System.out.println("Objective value: " + objectiveFunction(bestState));
}
}

C++

#include <iostream>
#include <vector>
#include <cmath>
#include <random>
#include <algorithm>

double objectiveFunction(const std::vector<int>& state) {
return std::accumulate(state.begin(), state.end(), 0.0);
}

std::vector<int> perturb(const std::vector<int>& state) {
std::vector<int> newState = state;
std::swap(newState[rand() % state.size(), rand() % state.size()]);
return newState;
}

std::vector<int> simulatedAnnealing(std::vector<int> initialState, double temperature, double coolingRate, int maxIterations) {
std::vector<int> currentState = initialState;
double currentEnergy = objectiveFunction(currentState);

for (int i = 0; i < maxIterations; i++) {
auto newState = perturb(currentState);
double newEnergy = objectiveFunction(newState);

if (newEnergy < currentEnergy) {
currentState = newState;
currentEnergy = newEnergy;
} else {
double acceptanceProbability = exp((currentEnergy - newEnergy) / temperature);
if ((static_cast<double>(rand()) / RAND_MAX) < acceptanceProbability) {
currentState = newState;
currentEnergy = newEnergy;
}
}

temperature *= coolingRate;
}

return currentState;
}

int main() {
std::vector<int> initialState = {5, 3, 1, 7, 2, 4, 6};
double temperature = 1000.0;
double coolingRate = 0.95;
int maxIterations = 1000;

auto bestState = simulatedAnnealing(initialState, temperature, coolingRate, maxIterations);
std::cout << "Best state: ";
for (const auto& val : bestState) {
std::cout << val << " ";
}
std::cout << "\nObjective value: " << objectiveFunction(bestState) << std::endl;

return 0;
}

Python

import math
import random

class SimulatedAnnealing:
    def __init__(self, cooling_rate=0.99):
        self.temperature = 1000
        self.cooling_rate = cooling_rate
    
    def find_solution(self, distances):
        current = self.initialize_solution(len(distances))
        best = current.copy()
        
        while self.temperature > 1:
            next = self.perturb_solution(current)
            delta = self.calculate_cost(distances, next) - self.calculate_cost(distances, current)
            if self.accept(delta):
                current = next
                if self.is_better(current, best):
                    best = current.copy()
            self.temperature *= self.cooling_rate
        return best
    
    def accept(self, delta):
        return math.exp(-delta / self.temperature) > random.random()

Go

package main

import (
"fmt"
"math"
"math/rand"
"time"
)

func objectiveFunction(state []int) float64 {
sum := 0
for _, v := range state {
sum += v
}
return float64(sum)
}

func perturb(state []int) []int {
newState := make([]int, len(state))
copy(newState, state)
i, j := rand.Intn(len(state)), rand.Intn(len(state))
newState[i], newState[j] = newState[j], newState[i]
return newState
}

func simulatedAnnealing(initialState []int, temperature, coolingRate float64, maxIterations int) []int {
currentState := initialState
currentEnergy := objectiveFunction(currentState)

for i := 0; i < maxIterations; i++ {
newState := perturb(currentState)
newEnergy := objectiveFunction(newState)

if newEnergy < currentEnergy {
currentState = newState
currentEnergy = newEnergy
} else {
acceptanceProbability := math.Exp((currentEnergy - newEnergy) / temperature)
if rand.Float64() < acceptanceProbability {
currentState = newState
currentEnergy = newEnergy
}
}
temperature *= coolingRate
}

return currentState
}

func main() {
rand.Seed(time.Now().UnixNano())
initialState := []int{5, 3, 1, 7, 2, 4, 6}
temperature := 1000.0
coolingRate := 0.95
maxIterations := 1000

bestState := simulatedAnnealing(initialState, temperature, coolingRate, maxIterations)
fmt.Println("Best state:", bestState)
fmt.Println("Objective value:", objectiveFunction(bestState))
}

八、实际服务应用场景的代码框架

        在物流配送系统中,模拟退火算法可以用于优化配送路径,减少配送时间和成本。系统会根据实时交通数据、配送点位置等信息,不断调整配送路径,以达到最优配送效果。

        为一个无线网络调度问题应用模拟退火算法,整个代码框架示例:

wireless_network_optimization/
├── main.py # 主程序入口
├── optimization.py # 模拟退火算法实现
├── network.py # 网络相关数据结构及功能实现
└── utils.py # 其他辅助函数

main.py 实现

from optimization import SimulatedAnnealing
from network import Network

def main():
network = Network()
initial_configuration = network.get_initial_configuration()

best_configuration = SimulatedAnnealing.run(
initial_configuration,
temperature=1000,
cooling_rate=0.95,
max_iterations=1000,
objective_function=network.objective_function
)

print("最优配置:", best_configuration)
print("最优目标值:", network.objective_function(best_configuration))

if __name__ == "__main__":
main()

optimization.py 实现

import math
import random

class SimulatedAnnealing:

@staticmethod
def run(initial_state, temperature, cooling_rate, max_iterations, objective_function):
current_state = initial_state
current_energy = objective_function(current_state)

for i in range(max_iterations):
new_state = SimulatedAnnealing.perturb(current_state)
new_energy = objective_function(new_state)

if new_energy < current_energy:
current_state = new_state
current_energy = new_energy
else:
acceptance_probability = math.exp((current_energy - new_energy) / temperature)
if random.random() < acceptance_probability:
current_state = new_state
current_energy = new_energy

temperature *= cooling_rate

return current_state

@staticmethod
def perturb(state):
# 定义扰动逻辑
pass

network.py 实现

class Network:
def __init__(self):
# 初始化网络相关参数
pass

def get_initial_configuration(self):
# 获取初始配置
pass

def objective_function(self, configuration):
# 计算目标函数
pass

utils.py 实现

# 辅助函数,可能包含数据处理等
def load_data(file_path):
# 加载数据
pass

def save_results(results, file_path):
# 保存结果
pass

        模拟退火算法(Simulated Annealing, SA)是一种启发式全局优化算法,灵感来源于固体退火原理。在冶金学中,退火是将金属加热到一定温度,再缓慢冷却以消除内部应力,使金属结构达到稳定状态。在优化问题中,模拟退火算法通过接受一定概率的“坏解”(即解质量下降的情况),以跳出局部最优,最终逼近全局最优解。

        模拟退火算法是一种强大并且灵活的优化算法,适合多种应用场景。

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

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

相关文章

NS4263 3.0Wx2 双声道 AB/D 类双模音频功率放大器附加耳机模式

1 特性 ● 工作电压范围:3.0V-5.25V ● AB 类和 D类工作模式切换 ● 一线脉冲控制工作模式与关断模式 ● 内置立体声耳机输出功能 ● 输出功率 3WClass D/Load4ohm ● THDN0.1%VDD5V/Po1W ● 优异的全带宽 EMI抑制能力 ● 优异的“上电和掉电”噪声抑制 ● 内置过流保护、欠压保…

PMP证书可不可以挂靠?看看考过的人怎么说

或许我们经常听到人们说可以把律师证、注册会计师证等挂靠在单位&#xff0c;从而每年获得额外收入。但是需要说明的是&#xff0c;PMP证书并不适用于挂靠这种情况。因为PMP并不属于我国体制内的职业资格证书&#xff0c;企业升级资质也不需要使用PMP证书&#xff0c;所以PMP是…

unity导入半透明webm + AE合成半透明视频

有些webm的文件导入unity后无法正常播报&#xff0c;踩坑好久才知道需要webm中的&#xff1a;VP8 标准 现在手上有几条mp4双通道的视频&#xff0c;当然unity中有插件是可以支持这种视频的&#xff0c;为了省事和代码洁癖&#xff0c;毅然决然要webm走到黑。 mp4导入AE合成半透…

如何使用dcmtk将dcm数据集中信息输出到可读文件

1. 缘起 在生成RDSR报告时候&#xff0c;代码中已经将患者的一些信息写入到dcm数据集中&#xff0c;但是最后保存的文件中没有这些值&#xff0c;因此需要将过程中的数据集信息打印出来&#xff0c;看是在什么地方出现问题了。 2. 将数据值保存到文件 std::unique_ptr<Dc…

“月薪3w,被人工智能玩弄。“

自从有了萝卜快跑无人驾驶车&#xff0c;一天天的都要被这些梗笑死&#xff1a; 萝卜快跑的萝卜&#xff0c;是指的乘客我吧&#xff1f;&#xff1f;&#xff1f; 15公里的路程&#xff0c;乘客自己追了14公里&#xff0c;还停在路中央让乘客上车哈哈哈哈&#xff01; 好消…

MATLAB求解微分方程和微分方程组的详细分析

目录 引言 微分方程的定义 MATLAB求解常微分方程 参数分析&#xff1a; MATLAB求解偏微分方程 刚性和非刚性问题 总结 引言 微分方程在物理、工程、经济和生物等多个领域有着广泛的应用。它们用于描述系统中变量与其导数之间的关系&#xff0c;通过这些方程可以解释和预…

如何通过可视化大屏,打通智慧城市建设的“最后一公里”?

在智慧城市的宏伟蓝图中&#xff0c;技术的融合与创新是推动城市发展的关键力量。然而&#xff0c;真正的挑战在于如何将这些技术成果转化为市民的实际体验&#xff0c;实现智慧城市建设的“最后一公里”。可视化大屏&#xff0c;作为连接技术与市民的桥梁&#xff0c;正以其独…

【吉利汽车安全应急响应中心-登录/注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

ssl证书过期怎么解决

SSL证书过期的解决方案主要是及时续费或更换新的SSL证书重新部署。rak小编为您整理发布具体解决方法。 当SSL证书即将过期时&#xff0c;最有效的方法是提前进行续费。 在证书到期前办理续费可以确保服务的连续性&#xff0c;并避免因证书失效而引发的网站访问问题。一旦续费完…

如何在HTML中实现m3u8视频播放:多种解决方案大比拼

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 HTML & M3U8 📒📝 HTML 播放 m3u8 的方式1. Video.js2. hls.js3. DPlayer📝 优缺点对比📝 使用建议📝 常见问题及解决方案⚓ 相关链接 ⚓📖 介绍 📖 在网页上播放 m3u8 格式的视频已经成为主流,尤其是在直播…

AI制药领域的中英文对照表

AI制药&#xff08;AIDD&#xff09;是指利用AI技术在药物研发、药物设计、药物筛选、临床试验和药物生产等各个环节中应用的制 药领域。AI在药物研发中可以通过数据挖掘、机器学习和深度学习等技术&#xff0c;加速药物发现和设计过程&#xff0c;提高研发 效率和成功率。AI还…

常见分组加密算法的整体结构

常见分组加密算法的整体结构 0x1 两分支平衡Feistel结构(典型) S(i)为Feistel结构密码的第i1轮中间输入状态&#xff0c;S(i1)为第i1轮中间输出状态。则其轮函数为 0x2 四分支非平衡Feistel结构(非典型) S(i)为四分支非平衡Feistel结构密码的第i1轮中间输入状态&#xff0c;…

【linux005】目录操作命令篇 - pstree 命令

文章目录 1、基本用法2、常见选项3、举例4、注意事项 pstree 命令在 Linux 中用于以树状结构显示进程及其子进程的层次结构。它提供了一种直观的方式来查看进程的父子关系&#xff0c;与 ps 命令的线性输出相比&#xff0c; pstree 更容易理解进程的继承关系 1、基本用法 ps…

【Python机器学习】循环神经网络(RNN)——审察模型内部情况

Keras附带了一些工具&#xff0c;比如model.summary()&#xff0c;用于审察模型内部情况。随着模型变得越来越复杂&#xff0c;我们需要经常使用model.summary()&#xff0c;否则在调整超参数时跟踪模型内部的内容的变化情况会变得非常费力。如果我们将模型的摘要以及验证的测试…

【无线通信发展史⑩】奥斯特的发现揭开了物理学史上的一个新纪元,奠定了电生磁的基础

前言&#xff1a;用这几个问答形式来解读下我这个系列的来龙去脉。如果大家觉得本篇文章不水的话希望帮忙点赞收藏加关注&#xff0c;你们的鼓舞是我继续更新的动力。 我为什么会写这个系列呢&#xff1f; 首先肯定是因为我本身就是一名从业通信者&#xff0c;想着更加了解自…

【1】OpenCV虚拟环境搭建

文章目录 OpenCV虚拟环境搭建&#xff08;一&#xff09;安装anaconda&#xff08;二&#xff09;anaconda修改虚拟环境默认位置STEP1&#xff1a;找到C:\Users\你的用户名下的.condarc文件STEP2&#xff1a;修改指定文件夹的权限&#xff08;重点&#xff09; &#xff08;三&…

supervisor安装CeSi集中化管理Supervisor

一、安装supervisor 备注&#xff1a;supervisor 只能管理前台进程的服务&#xff0c;比如 npm run 这些 &#xff0c;一些后台运行的服务无法管理【后台运行的服务可以用systemd 进行管理】 1、安装epel源 yum install epel-release yum install -y supervisor 2、创建sup…

udp网络通信 socket

套接字是实现进程间通信的编程。IP可以标定主机在全网的唯一性&#xff0c;端口可以标定进程在主机的唯一性&#xff0c;那么socket通过IP端口号就可以让两个在全网唯一标定的进程进行通信。 套接字有三种&#xff1a; 域间套接字&#xff1a;实现主机内部的进程通信的编程 …

02 三数排序

题目&#xff1a; 代码&#xff1a; #include <stdlib.h> #include<stdio.h>void swap(int *x,int *y) {if(*x>*y){int temp*x;*x*y;*ytemp;} }int main() {int x,y,z;scanf("%d %d %d",&x,&y,&z);swap(&x,&y);swap(&y,&…

漏洞复现-赛蓝-企业管理系统

本文来自无问社区&#xff0c;更多漏洞复现可前往查看http://www.wwlib.cn/index.php/index 0x01 产品简介 赛蓝企业管理系统是一款为企业提供全面管理解决方案的软件系统&#xff0c;它能够帮助企业实现精细化管理&#xff0c;提高效率&#xff0c;降低成本。系统集成了多种…