元启发式方法之模拟退火算法
来源:互联网 发布:澳大利亚外卖软件 编辑:程序博客网 时间:2024/05/17 17:17
模拟退火也叫做蒙特卡罗退火、统计冷却、概率爬山、随机松弛和概率交换算法,它来自于对热力学过程的模拟。为了生成规则晶体,先将原材料加热到熔化状态,再将晶体熔融液徐徐降温,使之凝固成晶体结构。在冷却过程中,如果降温太快,则会带来一些不良后果,特别是导致所形成的晶体不够规则,并且能量远远高于一个完美结构的晶体。物理系统和优化问题之间有明显的相似点,例如,物理系统中的能量就相当于优化问题的评估函数;快速淬火就相当于局部搜索;徐徐退火就相当于模拟退火的过程;温度就相当于模拟退火的控制参数T(后面有详细内容)等等。
在搜索过程中如果过早结束,就会陷入局部最优的情况,为了跳出局部最优,引入一个接受概率P和参数T。在当前解的邻域内选择一点,如果比当前解好,则总是接受它;如果没有当前解好则以接受概率接受它。注意,接受概率中的T是随着时间从大到小变化的(冷却温度),一开始T值很大,近似于随机搜索(随机选择当前解);后来T很小,近似于普通搜索法(选择最优作为当前解)。其中接受概率的定义为:
这是针对极大化问题的,如果是极小化问题则只需将指数的分子的两个变量交换位置。
由公式可以看出,当T很大时,则两个点的质量竞争的重要性就很小,对结果影响不大,这是概率接近于0.5,等同于随机选取;当T很小(T=1)时,概率接近于1,这就退化为普通局部搜索法了(每次都选择较优解作为当前解)。因此,T的值选择依据问题而定,既不能太大,也不能太小。另外,当T值固定时,如果新解与当前解质量相当,那么p为0.5;如果新解好于当前解,那么p大于0.5,而且新解越好,接受的概率就越大。这些事实都是符合常理的。
下面以TSP问题为例,给出模拟退火算法的一种实现(java实现):import java.util.ArrayList;import java.util.Random;import tools.TSPData;import interfaces.IRunning;/* * 使用模拟退火方法求解TSP问题 */public class SASolver implements IRunning{//当前解private ArrayList<Integer> current;//邻域内下一个解private ArrayList<Integer> next;//城市数量private int number;//开始的城市标号private int origin;//城市信息文件名private String file;//近似最优解private double shortestDist;//距离矩阵private double[][] distances; public SASolver(String filename){file = filename;shortestDist = 0;current = new ArrayList<Integer>();next = new ArrayList<Integer>();}@Overridepublic void run() {//搜索迭代次数int iteration = number * 2;//退火温度 double T = 10000.0; //退火速率 double cRate = 0.9999; //凝固温度 double ST = 0.00001; //随机数发生器 Random rand = new Random(System.nanoTime()); initialSolution(); double dist = getTotalDist(current); shortestDist = dist; origin = 0; while(T > ST){int count = iteration;double nextDist;dist = shortestDist;while(count > 0){getNextSolution();nextDist = getTotalDist(next);if (nextDist < dist) {current = (ArrayList<Integer>) next.clone();shortestDist = nextDist;} else {double r = rand.nextDouble();if (r < Math.exp((dist - nextDist) / T)) {current = (ArrayList<Integer>) next.clone();shortestDist = nextDist;}}count--;}T *= cRate;} //shortestDist = dist; System.out.println("算法结束");} /* * 总是根据当前解生成邻域新解 */private void getNextSolution() {next = (ArrayList<Integer>)current.clone();Random rand = new Random(System.nanoTime());//这里的算子:随机交换两个城市的位置(0作为起始点除外)int index1 = rand.nextInt(number - 1) + 1;int index2 = index1;while(index2 == index1)index2 = rand.nextInt(number - 1) + 1;int temp = next.get(index1);next.set(index1, next.get(index2));next.set(index2, temp);}private void initialSolution() {int i;for(i = 0; i < number; i++){if(i != origin) current.add(i);}current.add(0, origin);}private double getTotalDist(ArrayList<Integer> list) {double res = 0;int i = 0;for(; i < number - 1; i++)res += distances[list.get(i)][list.get(i + 1)];if(number > 1)res += distances[list.get(number - 1)][0];return res;}@Overridepublic void init() {distances = TSPData.getDistances(file);number = distances[0].length;}@Overridepublic void print() {System.out.println("算法得到的近似最优解为:" + shortestDist);System.out.println("该解对应的路径为:");int i;for(i = 0; i < number; i++)System.out.print(current.get(i) + "-->");System.out.println(current.get(0));}}
这里使用的算子是随机交换两个城市的位置。 实验得到的解(18左右)与最优解(14)很相近。 (待修订)
- 元启发式方法之模拟退火算法
- 现代启发式算法--初步了解模拟退火算法
- 现代启发式算法(二)——模拟退火算法
- 启发式与元启发式算法
- 从遗传算法、粒子群算法、模拟退火算法理解启发式算法优化的本质
- 模拟退火算法之运用实例
- TSP 之模拟退火算法 cpp实现
- 现代优化算法 之 模拟退火
- TSP问题之模拟退火算法
- 经典算法之—模拟退火
- “模拟退火算法的并行化”之“什么是模拟退火算法”
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火,遗传算法
- 模拟退火算法概述
- 模拟退火算法
- 遗传模拟退火算法
- Linux内核参数优化
- Windows Sockets编程模型详解
- 有没有认识中科大计算机的朋友啊,如有,请帮个忙,我今年考科大研究生,想找个好导师
- 【数据结构与算法】二叉堆
- Android Tomcat 的应用之客户端部分
- 元启发式方法之模拟退火算法
- 循环队列(数据结构)
- ISTQB - 名词解释
- 计算机--常用技术网站
- java.io.File操作文件的一些常用方法
- JS 动态加载下拉框
- Spring容器Bean的实例化方式和声明周期
- Xen的Hypervisor和Domain0的关系
- java学习7--Java I/O 操作与字节流