运行结果
视频演示
源码:
#include
#include
#include
#include
using namespace cv;
class TravelSalesman
{
private :
const std::vector& posCity;//城市坐标
std::vector& next;//后续城市索引向量;路线末端索引向量
RNG rng;
int d0,d1,d2,d3;//随机城市索引,以及后续三个城市索引
public:
TravelSalesman(std::vector &p, std::vector &n) :
posCity(p), next(n)
{
rng = theRNG();
}
/**给出系统状态的能量值。Give energy value for a state of system.*/
double energy() const;
/** 改变系统状态的函数(随机扰动) Function which change the state of system (random perturbation).*/
void changeState();
/** 反转到先前状态的函数 Function to reverse to the previous state.*/
void reverseState();
};
//改变状态
void TravelSalesman::changeState()
{
d0 = rng.uniform(0,static_cast(posCity.size()));//随机选择一个城市
d1 = next[d0];//下一个城市
d2 = next[d1];
d3 = next[d2];
//交换这个城市后续三个城市顺序 1-2-3 改为 2-3-1
next[d0] = d2;
next[d2] = d1;
next[d1] = d3;
}
//恢复状态改变
void TravelSalesman::reverseState()
{
next[d0] = d1;
next[d1] = d2;
next[d2] = d3;
}
//能量:路线总长度
double TravelSalesman::energy() const
{
double e = 0;
for (size_t i = 0; i < next.size(); i++)
{
e += norm(posCity[i]-posCity[next[i]]);
}
return e;
}
//绘制路线图
static void DrawTravelMap(Mat &img, std::vector &p, std::vector &n)
{
for (size_t i = 0; i < n.size(); i++)
{
circle(img,p[i],5,Scalar(0,0,255),2);//城市坐标点画圆:红色
line(img,p[i],p[n[i]],Scalar(0,255,0),2);//绿色:路线
}
}
int main(void)
{
int nbCity=40;//城市数量
Mat img(500,500,CV_8UC3,Scalar::all(0));//500*500背景图
RNG rng(123456);//随机数生成器
int radius=static_cast(img.cols*0.45);//半径
Point center(img.cols/2,img.rows/2);//圆心
std::vector posCity(nbCity);//城市坐标
std::vector next(nbCity);//路线末端索引顺序
for (size_t i = 0; i < posCity.size(); i++)
{
double theta = rng.uniform(0., 2 * CV_PI);//随机角度
posCity[i].x = static_cast(radius*cos(theta)) + center.x;//随机坐标点
posCity[i].y = static_cast(radius*sin(theta)) + center.y;
next[i]=(i+1)%nbCity;//路线末端坐标索引向量
}
TravelSalesman ts_system(posCity, next);//城市坐标和坐标索引
DrawTravelMap(img,posCity,next);//绘制初始旅行图
imshow("Map",img);
waitKey(10);
double currentTemperature = 100.0;//当前温度100
for (int i = 0, zeroChanges = 0; zeroChanges < 10; i++)
{//模拟退火算法(Simulated Annealing,SA)
int changesApplied = ml::simulatedAnnealingSolver(ts_system, currentTemperature, currentTemperature*0.97, 0.99, 10000*nbCity, ¤tTemperature, rng);
img.setTo(Scalar::all(0));//清空背景
DrawTravelMap(img, posCity, next);//绘制新的路线图
imshow("Map", img);
int k = waitKey(10);
std::cout << "i=" << i << " changesApplied=" << changesApplied << " temp=" << currentTemperature << " result=" << ts_system.energy() << std::endl;
if (k == 27 || k == 'q' || k == 'Q')
return 0;
if (changesApplied == 0)
zeroChanges++;//未发生改变次数=10时停止计算
}
std::cout << "Done" << std::endl;
waitKey(0);
return 0;
}
迭代过程:
i=0 changesApplied=808216 temp=96.0596 result=5881.56
i=1 changesApplied=858262 temp=92.2745 result=4128.39
i=2 changesApplied=833786 temp=88.6385 result=6112.83
i=3 changesApplied=792061 temp=85.1458 result=6531.22
i=4 changesApplied=821249 temp=81.7907 result=4288.95
i=5 changesApplied=884042 temp=78.5678 result=3332.4
i=6 changesApplied=839431 temp=75.4719 result=3825.27
i=7 changesApplied=869839 temp=72.498 result=3317.85
i=8 changesApplied=845716 temp=69.6413 result=3297.11
i=9 changesApplied=904058 temp=66.8972 result=3155.89
i=10 changesApplied=881034 temp=64.2612 result=2944.53
i=11 changesApplied=873954 temp=61.729 result=2601.67
i=12 changesApplied=843252 temp=59.2966 result=2467.88
i=13 changesApplied=864529 temp=56.9601 result=2231.8
i=14 changesApplied=853781 temp=54.7157 result=2594.18
i=15 changesApplied=830185 temp=52.5596 result=3025.01
i=16 changesApplied=818816 temp=50.4886 result=2285.11
i=17 changesApplied=807015 temp=48.4991 result=2664.99
i=18 changesApplied=753353 temp=46.5881 result=3251.8
i=19 changesApplied=711730 temp=44.7523 result=3153.88
i=20 changesApplied=706083 temp=42.9889 result=2541.9
i=21 changesApplied=704105 temp=41.295 result=2256.83
i=22 changesApplied=705435 temp=39.6678 result=2500.24
i=23 changesApplied=694150 temp=38.1047 result=2166.88
i=24 changesApplied=662084 temp=36.6032 result=2470.48
i=25 changesApplied=647592 temp=35.1609 result=1599.8
i=26 changesApplied=651940 temp=33.7754 result=1825.39
i=27 changesApplied=634531 temp=32.4446 result=1956.51
i=28 changesApplied=613019 temp=31.1661 result=1745.61
i=29 changesApplied=595086 temp=29.938 result=1548.85
i=30 changesApplied=575871 temp=28.7584 result=1825.46
i=31 changesApplied=556314 temp=27.6252 result=1895.87
i=32 changesApplied=538315 temp=26.5366 result=1508.17
i=33 changesApplied=521729 temp=25.491 result=1546.52
i=34 changesApplied=502658 temp=24.4865 result=1617.17
i=35 changesApplied=487747 temp=23.5217 result=1472.48
i=36 changesApplied=473215 temp=22.5948 result=1459.04
i=37 changesApplied=455032 temp=21.7045 result=1488.05
i=38 changesApplied=439625 temp=20.8492 result=1605.31
i=39 changesApplied=423325 temp=20.0277 result=1608.03
i=40 changesApplied=410123 temp=19.2385 result=1468.27
i=41 changesApplied=395997 temp=18.4805 result=1435.8
i=42 changesApplied=383356 temp=17.7523 result=1629.44
i=43 changesApplied=371449 temp=17.0527 result=1519.21
i=44 changesApplied=359105 temp=16.3808 result=1542.89
i=45 changesApplied=348483 temp=15.7353 result=1504.81
i=46 changesApplied=339205 temp=15.1153 result=1480.63
i=47 changesApplied=328084 temp=14.5197 result=1420.31
i=48 changesApplied=317479 temp=13.9476 result=1433.18
i=49 changesApplied=307721 temp=13.398 result=1433.11
i=50 changesApplied=300116 temp=12.87 result=1418.04
i=51 changesApplied=290846 temp=12.3629 result=1464.58
i=52 changesApplied=282452 temp=11.8758 result=1435.92
i=53 changesApplied=273292 temp=11.4078 result=1434.7
i=54 changesApplied=266020 temp=10.9583 result=1408.05
i=55 changesApplied=258220 temp=10.5265 result=1424.75
i=56 changesApplied=250910 temp=10.1117 result=1436.64
i=57 changesApplied=243815 temp=9.71326 result=1463.3
i=58 changesApplied=236620 temp=9.33052 result=1418.04
i=59 changesApplied=230336 temp=8.96286 result=1468.57
i=60 changesApplied=222956 temp=8.60969 result=1415.95
i=61 changesApplied=217409 temp=8.27043 result=1409.61
i=62 changesApplied=210947 temp=7.94455 result=1405.24
i=63 changesApplied=204279 temp=7.6315 result=1423.12
i=64 changesApplied=198443 temp=7.33079 result=1415.3
i=65 changesApplied=192288 temp=7.04192 result=1426.82
i=66 changesApplied=186591 temp=6.76444 result=1415.94
i=67 changesApplied=180977 temp=6.4979 result=1431.56
i=68 changesApplied=175411 temp=6.24186 result=1425.93
i=69 changesApplied=168896 temp=5.9959 result=1421.22
i=70 changesApplied=164013 temp=5.75964 result=1417.51
i=71 changesApplied=157937 temp=5.53269 result=1408.05
i=72 changesApplied=152650 temp=5.31468 result=1410.87
i=73 changesApplied=147503 temp=5.10526 result=1417.58
i=74 changesApplied=141804 temp=4.90409 result=1413.67
i=75 changesApplied=136601 temp=4.71085 result=1427.56
i=76 changesApplied=131146 temp=4.52522 result=1419.66
i=77 changesApplied=125419 temp=4.34691 result=1415.95
i=78 changesApplied=120823 temp=4.17563 result=1408.05
i=79 changesApplied=115183 temp=4.01109 result=1415.22
i=80 changesApplied=110339 temp=3.85304 result=1415.94
i=81 changesApplied=105474 temp=3.70121 result=1408.05
i=82 changesApplied=100502 temp=3.55537 result=1412.42
i=83 changesApplied=95868 temp=3.41527 result=1409.68
i=84 changesApplied=91972 temp=3.2807 result=1412.42
i=85 changesApplied=87166 temp=3.15142 result=1418.11
i=86 changesApplied=82091 temp=3.02725 result=1405.24
i=87 changesApplied=77753 temp=2.90796 result=1415.94
i=88 changesApplied=73221 temp=2.79338 result=1405.24
i=89 changesApplied=69066 temp=2.68331 result=1405.24
i=90 changesApplied=65379 temp=2.57757 result=1409.68
i=91 changesApplied=61093 temp=2.47601 result=1405.24
i=92 changesApplied=57568 temp=2.37844 result=1405.24
i=93 changesApplied=53332 temp=2.28472 result=1405.24
i=94 changesApplied=50596 temp=2.19469 result=1405.24
i=95 changesApplied=46887 temp=2.10821 result=1408.05
i=96 changesApplied=43185 temp=2.02514 result=1405.24
i=97 changesApplied=39924 temp=1.94534 result=1405.24
i=98 changesApplied=37259 temp=1.86869 result=1408.05
i=99 changesApplied=34352 temp=1.79506 result=1408.05
i=100 changesApplied=31071 temp=1.72432 result=1405.24
i=101 changesApplied=29008 temp=1.65638 result=1405.24
i=102 changesApplied=26136 temp=1.59111 result=1405.24
i=103 changesApplied=23950 temp=1.52841 result=1405.24
i=104 changesApplied=21732 temp=1.46819 result=1405.24
i=105 changesApplied=20058 temp=1.41034 result=1405.24
i=106 changesApplied=17912 temp=1.35476 result=1405.24
i=107 changesApplied=16335 temp=1.30138 result=1408.05
i=108 changesApplied=14671 temp=1.2501 result=1405.24
i=109 changesApplied=13050 temp=1.20084 result=1405.24
i=110 changesApplied=11808 temp=1.15352 result=1405.24
i=111 changesApplied=10295 temp=1.10807 result=1408.05
i=112 changesApplied=8961 temp=1.06441 result=1405.24
i=113 changesApplied=7962 temp=1.02247 result=1405.24
i=114 changesApplied=6978 temp=0.982176 result=1405.24
i=115 changesApplied=5970 temp=0.943475 result=1405.24
i=116 changesApplied=5282 temp=0.906298 result=1405.24
i=117 changesApplied=4720 temp=0.870586 result=1405.24
i=118 changesApplied=4024 temp=0.836282 result=1405.24
i=119 changesApplied=3418 temp=0.803329 result=1405.24
i=120 changesApplied=2936 temp=0.771675 result=1405.24
i=121 changesApplied=2390 temp=0.741268 result=1405.24
i=122 changesApplied=2134 temp=0.712059 result=1405.24
i=123 changesApplied=1708 temp=0.684001 result=1405.24
i=124 changesApplied=1540 temp=0.657048 result=1405.24
i=125 changesApplied=1207 temp=0.631158 result=1408.05
i=126 changesApplied=995 temp=0.606288 result=1405.24
i=127 changesApplied=928 temp=0.582398 result=1405.24
i=128 changesApplied=678 temp=0.559449 result=1405.24
i=129 changesApplied=566 temp=0.537404 result=1405.24
i=130 changesApplied=394 temp=0.516228 result=1405.24
i=131 changesApplied=386 temp=0.495887 result=1405.24
i=132 changesApplied=268 temp=0.476347 result=1405.24
i=133 changesApplied=264 temp=0.457577 result=1405.24
i=134 changesApplied=176 temp=0.439547 result=1405.24
i=135 changesApplied=152 temp=0.422227 result=1405.24
i=136 changesApplied=108 temp=0.405589 result=1405.24
i=137 changesApplied=54 temp=0.389608 result=1405.24
i=138 changesApplied=58 temp=0.374256 result=1405.24
i=139 changesApplied=54 temp=0.359508 result=1405.24
i=140 changesApplied=28 temp=0.345342 result=1405.24
i=141 changesApplied=16 temp=0.331734 result=1405.24
i=142 changesApplied=12 temp=0.318663 result=1405.24
i=143 changesApplied=6 temp=0.306106 result=1405.24
i=144 changesApplied=8 temp=0.294044 result=1405.24
i=145 changesApplied=2 temp=0.282458 result=1405.24
i=146 changesApplied=2 temp=0.271328 result=1405.24
i=147 changesApplied=4 temp=0.260636 result=1405.24
i=148 changesApplied=0 temp=0.250366 result=1405.24
i=149 changesApplied=4 temp=0.240501 result=1405.24
i=150 changesApplied=0 temp=0.231024 result=1405.24
i=151 changesApplied=0 temp=0.221921 result=1405.24
i=152 changesApplied=0 temp=0.213176 result=1405.24
i=153 changesApplied=0 temp=0.204776 result=1405.24
i=154 changesApplied=0 temp=0.196707 result=1405.24
i=155 changesApplied=0 temp=0.188956 result=1405.24
i=156 changesApplied=0 temp=0.181511 result=1405.24
i=157 changesApplied=0 temp=0.174358 result=1405.24
i=158 changesApplied=0 temp=0.167488 result=1405.24
Done
笔记:
/** @brief The class implements simulated annealing for optimization.
@cite Kirkpatrick83 for details
@param solverSystem optimization system (see SimulatedAnnealingSolverSystem)
@param initialTemperature initial temperature
@param finalTemperature final temperature
@param coolingRatio temperature step multiplies
@param iterationsPerStep number of iterations per temperature changing step
@param lastTemperature optional output for last used temperature
@param rngEnergy specify custom random numbers generator (cv::theRNG() by default)
*/
template
int simulatedAnnealingSolver(SimulatedAnnealingSolverSystem& solverSystem,
double initialTemperature, double finalTemperature, double coolingRatio,
size_t iterationsPerStep,
CV_OUT double* lastTemperature = NULL,
cv::RNG& rngEnergy = cv::theRNG()
);
/** @brief 该类实现模拟退火以进行优化。
@cite Kirkpatrick83 了解详情
@param solverSystem 优化系统(参见 SimulatedAnnealingSolverSystem)
@param initialTemperature 初始温度
@param finalTemperature 最终温度
@param coolingRatio 温度步长相乘
@param iterationsPerStep 每个温度变化步骤的迭代次数
@param lastTemperature 上次使用温度的可选输出
@param rngEnergy 指定自定义随机数生成器(默认为 cv::theRNG())
*/
int changesApplied = ml::simulatedAnnealingSolver(ts_system, currentTemperature, currentTemperature*0.97, 0.99, 10000*nbCity, ¤tTemperature, rng);
The End