模拟退火算法 Simulated Annealing

2023-12-03 00:30

本文主要是介绍模拟退火算法 Simulated Annealing,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

模拟退火算法 Simulated Annealing

1. 介绍

模拟退火算法(Simulated Annealing, SA)是一种启发式的优化算法。它适用于在大型离散或连续复杂问题中寻找全局最优解,例如组合优化,约束优化,图问题等。模拟退火是一种随机(概率性)搜索算法,基于物理中固体晶体退火过程的模拟。退火过程中,晶体内部由高能状态向低能状态演化,最终在足够低的温度时稳定在能量最低的状态。

模拟退火算法的主要思想是在搜索过程中接受比当前解差的解,以跳出局部最优。具体来说,模拟退火算法过程如下:

  1. 初始化设置:设置初始解、初始温度、温度衰减系数,最低温度等参数。

  2. 在当前温度下,随机选取一个邻近解并计算其能量变化量。

  3. 如果能量降低(对于最小化问题),则接受该解作为当前解;如果能量增加,则以一定的概率(通常依赖于温度和能量变化量)接受该解。

  4. 更新温度(通常为当前温度乘以衰减系数)。

  5. 重复步骤2-4,直到温度降至最低温度并稳定。

  6. 输出最佳解。

模拟退火算法的关键在于选择合适的初始温度、衰减系数和结束条件,以及针对问题的邻近解生成策略和概率接受函数。

2. 经典应用

接下来,我们将以三个经典问题为例,展示如何使用模拟退火算法求解。

2.1 旅行商问题(TSP)

旅行商问题即求解在给定城市、距离的情况下,找到一条道路,使得从起点出发,经过所有城市后回到起点,且总距离最短。

import random
import math
import numpy as np# 计算路径长度
def calculate_distance(path, distance_matrix):distance = 0for i in range(len(path)-1):distance += distance_matrix[path[i]][path[i+1]]distance += distance_matrix[path[-1]][path[0]]return distance# 邻近解生成策略:交换两个城市的位置
def generate_neighbor(path):new_path = path.copy()i, j = random.sample(range(len(path)), 2)new_path[i], new_path[j] = new_path[j], new_path[i]return new_path# 模拟退火算法求解TSP问题
def simulated_annealing_tsp(distance_matrix, initial_temperature, min_temperature, cooling_factor, max_iteration):n = len(distance_matrix)current_path = list(range(n))random.shuffle(current_path)current_distance = calculate_distance(current_path, distance_matrix)temperature = initial_temperaturebest_path = current_path[:]best_distance = current_distancefor it in range(max_iteration):if temperature < min_temperature:breaknew_path = generate_neighbor(current_path)new_distance = calculate_distance(new_path, distance_matrix)delta_distance = new_distance - current_distanceif delta_distance < 0:current_path = new_pathcurrent_distance = new_distanceif new_distance < best_distance:best_path = new_path[:]best_distance = new_distanceelse:prob = math.exp(-delta_distance / temperature)if random.random() < prob:current_path = new_pathcurrent_distance = new_distancetemperature *= cooling_factorreturn best_path, best_distance# 用随机距离矩阵测试
n = 10
distance_matrix = np.random.randint(1, 100, size=(n, n))
initial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000best_path, best_distance = simulated_annealing_tsp(distance_matrix, initial_temperature, min_temperature, cooling_factor, max_iteration)
print('Best path:', best_path)
print('Best distance:', best_distance)
2.2 函数寻优

给定一个连续空间的实数函数f(x),求解其在给定区间上的最小值。

import random
import math# 定义函数
def f(x):return x * x - 4 * x + 4def generate_neighbor(x, step):return x + random.uniform(-step, step)def simulated_annealing_function_optimization(f, initial_temperature, min_temperature, cooling_factor, max_iteration, search_interval, neighbor_step):current_x = random.uniform(search_interval[0], search_interval[1])current_y = f(current_x)temperature = initial_temperaturebest_x = current_xbest_y = current_yfor it in range(max_iteration):if temperature < min_temperature:breaknew_x = generate_neighbor(current_x, neighbor_step)if new_x < search_interval[0] or new_x > search_interval[1]:continuenew_y = f(new_x)delta_y = new_y - current_yif delta_y < 0:current_x = new_xcurrent_y = new_yif new_y < best_y:best_x = new_xbest_y = new_yelse:prob = math.exp(-delta_y / temperature)if random.random() < prob:current_x = new_xcurrent_y = new_ytemperature *= cooling_factorreturn best_x, best_yinitial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000
search_interval = [0, 5]
neighbor_step = 0.1best_x, best_y = simulated_annealing_function_optimization(f, initial_temperature, min_temperature, cooling_factor, max_iteration, search_interval, neighbor_step)
print('Best x:', best_x)
print('Best y:', best_y)
2.3 定点覆盖问题

给定一个二维平面,有若干个点和一定数量的覆盖盒。要求通过移动覆盖盒的位置使得尽可能多的点被覆盖。覆盖盒的形状为边长为1的正方形。

import random
import mathdef point_covered(points, box):# 判断点是否在覆盖盒内return sum([1 for p in points if box[0] <= p[0] <= box[0]+1 and box[1] <= p[1] <= box[1]+1])def generate_neighbor(box, step):# 随机生成一个相邻覆盖盒return (box[0] + random.uniform(-step, step), box[1] + random.uniform(-step, step))def simulated_annealing_point_cover(points, n_boxes, initial_temperature, min_temperature, cooling_factor, max_iteration, neighbor_step):boxes = [(random.uniform(0, 5), random.uniform(0, 5)) for _ in range(n_boxes)]temperature = initial_temperature# 当前解:覆盖的点数量和覆盖盒集合current_cover = sum([point_covered(points, box) for box in boxes])current_boxes = boxes# 迭代过程for it in range(max_iteration):if temperature < min_temperature:break# 随机选择一个覆盖盒生成相邻解idx = random.randrange(len(boxes))new_box = generate_neighbor(boxes[idx], neighbor_step)new_boxes = boxes[:]new_boxes[idx] = new_boxnew_cover = sum([point_covered(points, box) for box in new_boxes])delta_cover = new_cover - current_coverif delta_cover > 0:current_boxes = new_boxescurrent_cover = new_coverelse:prob = math.exp(delta_cover / temperature)if random.random() < prob:current_boxes = new_boxescurrent_cover = new_covertemperature *= cooling_factorreturn current_boxes# 生成点集
points = [(random.uniform(0, 5), random.uniform(0, 5)) for _ in range(50)]
n_boxes = 5initial_temperature = 1000
min_temperature = 1e-6
cooling_factor = 0.99
max_iteration = 10000
neighbor_step = 0.1result = simulated_annealing_point_cover(points, n_boxes, initial_temperature, min_temperature, cooling_factor, max_iteration, neighbor_step)
print(result)

以上三个案例展示了如何使用模拟退火算法求解旅行商问题、函数寻优以及定点问题。请注意,模拟退火算法在每个问题中的效果取决于选择的初始参数和邻近解生成策略。

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接: 人工智能交流群(大量资料)

在这里插入图片描述

这篇关于模拟退火算法 Simulated Annealing的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/447422

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

最大公因数:欧几里得算法

简述         求两个数字 m和n 的最大公因数,假设r是m%n的余数,只要n不等于0,就一直执行 m=n,n=r 举例 以18和12为例 m n r18 % 12 = 612 % 6 = 06 0所以最大公因数为:6 代码实现 #include<iostream>using namespace std;/