模拟退火算法-旅行商问题-matlab实现
整理一下数学建模会用到的算法,供比赛时候参考食用。
——————————————————————————————————————————
旅行商问题(TSP):
给定一系列城市和每对城市之间的距离,求解访问每一座城市一次并回到起始城市的最短回路。
它是组合优化中的一个NP困难问题,在运筹学和理论计算机科学中非常重要。
以下两个程序,在不同数据集合情况下表现有所差别,理论上第一个程序的解更为优化。
- clear
- clc
- a = 0.99; %温度衰减函数的参数
- t0 = ; %初始温度
- tf = ; %终止温度
- t = t0;
- Markov_length = ; %Markov链长度
- % load data.txt
- % x = data(:, ::); x = x(:);
- % y = data(:, ::); y = y(:);
- % data = [,;x, y];
- % coordinates = data;
- coordinates = [
- 565.0 575.0; 25.0 185.0; 345.0 750.0;
- 945.0 685.0; 845.0 655.0; 880.0 660.0;
- 25.0 230.0; 525.0 1000.0; 580.0 1175.0;
- 650.0 1130.0; 1605.0 620.0; 1220.0 580.0;
- 1465.0 200.0; 1530.0 5.0; 845.0 680.0;
- 725.0 370.0; 145.0 665.0; 415.0 635.0;
- 510.0 875.0; 560.0 365.0; 300.0 465.0;
- 520.0 585.0; 480.0 415.0; 835.0 625.0;
- 975.0 580.0; 1215.0 245.0; 1320.0 315.0;
- 1250.0 400.0; 660.0 180.0; 410.0 250.0;
- 420.0 555.0; 575.0 665.0; 1150.0 1160.0;
- 700.0 580.0; 685.0 595.0; 685.0 610.0;
- 770.0 610.0; 795.0 645.0; 720.0 635.0;
- 760.0 650.0; 475.0 960.0; 95.0 260.0;
- 875.0 920.0; 700.0 500.0; 555.0 815.0;
- 830.0 485.0; 1170.0 65.0; 830.0 610.0;
- 605.0 625.0; 595.0 360.0; 1340.0 725.0;
- 1740.0 245.0;
- ];
- coordinates(:,) = [];
- amount = size(coordinates,); %城市的数目
- %通过向量化的方法计算距离矩阵
- dist_matrix = zeros(amount,amount);
- coor_x_tmp1 = coordinates(:,) * ones(,amount);
- coor_x_tmp2 = coor_x_tmp1';
- coor_y_tmp1 = coordinates(:,) * ones(,amount);
- coor_y_tmp2 = coor_y_tmp1';
- dist_matrix = sqrt((coor_x_tmp1 - coor_x_tmp2).^ + (coor_y_tmp1 - coor_y_tmp2).^);
- sol_new = :amount; %产生初始解,sol_new是每次产生的新解
- sol_current = sol_new; %sol_current是当前解
- sol_best = sol_new; %sol_best是冷却中的最好解
- E_current = inf; %E_current是当前解对应的回路距离
- E_best = inf; %E_best是最优解
- p = ;
- rand('state', sum(clock));
- for j = :
- sol_current = [randperm(amount)];
- E_current = ;
- for i=:(amount-)
- E_current = E_current+dist_matrix(sol_current(i), sol_current(i+));
- end
- if E_current<E_best
- sol_best = sol_current;
- E_best = E_current;
- end
- end
- while t >= tf
- for r = :Markov_length %Markov链长度
- %产生随机扰动
- if(rand < 0.5)
- %两交换
- ind1 = ;
- ind2 = ;
- while(ind1 == ind2)
- ind1 = ceil(rand * amount);
- ind2 = ceil(rand * amount);
- end
- tmp1 = sol_new(ind1);
- sol_new(ind1) = sol_new(ind2);
- sol_new(ind2) = tmp1;
- else
- %三交换
- ind=ceil(amount*rand(,));
- ind = sort(ind);
- sol_new = sol_new(, [:ind()-, ind()+:ind(),ind():ind(),ind()+:end]);
- end
- %检查是否满足约束
- %计算目标函数值(即内能)
- E_new = ;
- for i = :(amount - )
- E_new = E_new + dist_matrix(sol_new(i),sol_new(i + ));
- end
- %再算上从最后一个城市到第一个城市的距离
- E_new = E_new + dist_matrix(sol_new(amount),sol_new());
- if E_new < E_current
- E_current = E_new;
- sol_current = sol_new;
- if E_new < E_best
- E_best = E_new;
- sol_best = sol_new;
- end
- else
- %若新解的目标函数值大于当前解,
- %则仅以一定概率接受新解
- if rand < exp(-(E_new - E_current) / t)
- E_current = E_new;
- sol_current = sol_new;
- else
- sol_new = sol_current;
- end
- end
- end
- t = t * a; %控制参数t(温度)减少为原来的a倍
- end
- E_best = E_best+dist_matrix(sol_best(end), sol_best());
- disp('最优解为:');
- disp(sol_best);
- disp('最短距离:');
- disp(E_best);
- data1 = zeros(length(sol_best), );
- for i = :length(sol_best)
- data1(i, :) = coordinates(sol_best(,i), :);
- end
- data1 = [data1; coordinates(sol_best(,),:)];
- figure
- plot(coordinates(:,)', coordinates(:,2)', '*k', data1(:,)', data1(:, 2)', 'r');
- title( [ '近似最短路径如下,路程为' , num2str( E_best ) ] ) ;
另一种根据《数学建模算法与应用—司守奎》中算法改编:
- clc;
- clear;
- close all;
- coordinates = [
- 25.0 185.0; 345.0 750.0;
- 945.0 685.0; 845.0 655.0; 880.0 660.0;
- 25.0 230.0; 525.0 1000.0; 580.0 1175.0;
- 650.0 1130.0; 1605.0 620.0; 1220.0 580.0;
- 1465.0 200.0; 1530.0 5.0; 845.0 680.0;
- 725.0 370.0; 145.0 665.0; 415.0 635.0;
- 510.0 875.0; 560.0 365.0; 300.0 465.0;
- 520.0 585.0; 480.0 415.0; 835.0 625.0;
- 975.0 580.0; 1215.0 245.0; 1320.0 315.0;
- 1250.0 400.0; 660.0 180.0; 410.0 250.0;
- 420.0 555.0; 575.0 665.0; 1150.0 1160.0;
- 700.0 580.0; 685.0 595.0; 685.0 610.0;
- 770.0 610.0; 795.0 645.0; 720.0 635.0;
- 760.0 650.0; 475.0 960.0; 95.0 260.0;
- 875.0 920.0; 700.0 500.0; 555.0 815.0;
- 830.0 485.0; 1170.0 65.0; 830.0 610.0;
- 605.0 625.0; 595.0 360.0; 1340.0 725.0;
- 1740.0 245.0;
- ];
- coordinates(:,) = [];
- data = coordinates;
- % 读取数据
- % load data.txt;
- % x = data(:, ::); x = x(:);
- % y = data(:, ::); y = y(:);
- x = data(:, );
- y = data(:, );
- start = [565.0 575.0];
- data = [start; data;start];
- % data = [start; x, y;start];
- % data = data*pi/;
- % 计算距离的邻接表
- count = length(data(:, ));
- d = zeros(count);
- for i = :count-
- for j = i+:count
- % temp = cos(data(i, )-data(j,))*cos(data(i,))*cos(data(j,))...
- % +sin(data(i,))*sin(data(j,));
- d(i,j)=( sum( ( data( i , : ) - data( j , : ) ) .^ ) ) ^ 0.5 ;
- % d(i,j) = *acos(temp);
- end
- end
- d =d + d'; % 对称 i到j==j到i
- S0=[]; % 存储初值
- Sum=inf; % 存储总距离
- rand('state', sum(clock));
- % 求一个较为优化的解,作为初值
- for j = :
- S = [ +randperm(count-), count];
- temp = ;
- for i=:count-
- temp = temp+d(S(i), S(i+));
- end
- if temp<Sum
- S0 = S;
- Sum = temp;
- end
- end
- e = 0.1^; % 终止温度
- L = ; % 最大迭代次数
- at = 0.999999; % 降温系数
- T = ; % 初温
- % 退火过程
- for k = :L
- % 产生新解
- c =+floor((count-)*rand(,));
- c = sort(c);
- c1 = c(); c2 = c();
- if c1==
- c1 = c1+;
- end
- if c2==
- c2 = c2+;
- end
- % 计算代价函数值
- df = d(S0(c1-), S0(c2))+d(S0(c1), S0(c2+))-...
- (d(S0(c1-), S0(c1))+d(S0(c2), S0(c2+)));
- % 接受准则
- if df<
- S0 = [S0(: c1-), S0(c2:-:c1), S0(c2+:count)];
- Sum = Sum+df;
- elseif exp(-df/T) > rand()
- S0 = [S0(: c1-), S0(c2:-:c1), S0(c2+:count)];
- Sum = Sum+df;
- end
- T = T*at;
- if T<e
- break;
- end
- end
- data1 = zeros(, count);
- % y1 = [start; x, y; start];
- for i =:count
- data1(:, i) = data(S0(,i), :)';
- end
- figure
- plot(x, y, 'o', data1(, :), data1(, :), 'r');
- title( [ '近似最短路径如下,路程为' , num2str( Sum ) ] ) ;
- disp(Sum);
- S0
模拟退火算法-旅行商问题-matlab实现的更多相关文章
- 模拟退火算法求解旅行商问题(附c和matlab源代码)
前几天在做孔群加工问题,各种假设到最后就是求解旅行商问题了,因为原本就有matlab代码模板所以当时就改了城市坐标直接用了,发现运行速度惨不忍睹,最后用上了两个队友的电脑一起跑.这次模拟结束后在想用c ...
- Matlab随笔之模拟退火算法
问题描述: 我方有一个基地,经度和纬度为( 70,40).假设我方飞机的速度为 1000 公里/小时. 我方派一架飞机从基地出发,侦察完敌方所有目标,再返回原来的基地.在敌方每一目 标点的侦察时间不计 ...
- 模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径
模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...
- 模拟退火算法(SA)求解TSP 问题(C语言实现)
这篇文章是之前写的智能算法(遗传算法(GA).粒子群算法(PSO))的补充.其实代码我老早之前就写完了,今天恰好重新翻到了,就拿出来给大家分享一下,也当是回顾与总结了. 首先介绍一下模拟退火算法(SA ...
- 模拟退火算法Python编程(2)约束条件的处理
1.最优化与线性规划 最优化问题的三要素是决策变量.目标函数和约束条件. 线性规划(Linear programming),是研究线性约束条件下线性目标函数的极值问题的优化方法,常用于解决利用现有的资 ...
- 模拟退火算法Python编程(3)整数规划问题
1.整数规划问题 整数规划问题在工业.经济.国防.医疗等各行各业应用十分广泛,是指规划中的变量(全部或部分)限制为整数,属于离散优化问题(Discrete Optimization). 线性规划问题的 ...
- 模拟退火算法-[HDU1109]
模拟退火算法的原理模拟退火算法来源于固体退火原理,将固体加温至充分高,再让其徐徐冷却,加温时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到 ...
- 【高级算法】模拟退火算法解决3SAT问题(C++实现)
转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46453761 ---------------------------------- ...
- 原创:工作指派问题解决方案---模拟退火算法C实现
本文忽略了对于模拟退火的算法的理论讲解,读者可参考相关的博文或者其他相关资料,本文着重于算法的实现: /************************************************ ...
随机推荐
- 存储过程中调用webservice
存储过程中调用webservice其实是在数据库中利用系统函数调用OLE. 1.查找webservice api 可得到MSSOAP.SoapClient. 2.查找API 接口可得到mssoapin ...
- mybatis-plus的代码生成器
简介:构建自定义mybatis-plus模板,自动生成mybatis,entity,mapper,service,controller 项目源码:https://github.com/y369q369 ...
- webview之如何设计一个优雅健壮的Android WebView?(下)(转)
转载:https://iluhcm.com/2018/02/27/design-an-elegant-and-powerful-android-webview-part-two/ (这篇文章写得有点晚 ...
- Java定时器小实例
有时候,我们需要在Java中定义一个定时器来轮询操作,比如每隔一段时间查询.删除数据库中的某些数据等,下面记录一下一种简单实现方式 1,首先新建一个类,类中编写方法来实现业务操作 public cla ...
- html/css/js----js中遇到的一些问题
学习前端的时候有时也会遇到一些弄不明白的问题,学习js会有更多的方法不清楚它的用法,我谨以在学习中遇到的一些问题记录下来,以便日复习! 一."window.opener.location.r ...
- SpringBoot 配置文件 中文乱码
本方案,支持springboot 很简单 在配置文件中不写中文,写中文的ascll码 直接百度在线转ASCII,用工具 把中文转ASCII码==>\u628a\u4e2d\u6587\u8f6c ...
- WebBrowser2控件使用
一 简介 这是一个IE实现的com接口, 简单的浏览一个网页可以用这个东西, 局限性是IE现在有好多版本, 不同版本对标准的支持是不一样的, 而且将来不排除windows把IE给干掉了 二 使用 1 ...
- 怎么精确控制solidworks里面的表格的位置
手工移动是不可能的,总是有点误差,虽然有主动捕捉的功能. public void SetTablePosition(TableAnnotation table, double x, double y) ...
- Java经典代码片段——使用NIO进行快速的文件拷贝
public static void fileCopy(File in, File out) throws IOException { FileChannel inChannel = new File ...
- oracle表的基本操作
--修改名称rename l_user_info to t_user_info --添加带有约束的表 create table t_user_menu( id number(20) primary k ...