模拟退火算法
来源:互联网 发布:爱淘宝红包 返利 编辑:程序博客网 时间:2024/06/05 16:26
转自:
http://www.cnblogs.com/CsOH/p/6049117.html
有 N ( <=20 ) 台 PC 放在机房内,现在要求由你选定一台 PC,用共 N-1 条网线从这台机器开始一台接一台地依次连接他们,最后接到哪个以及连接的顺序也是由你选定的,为了节省材料,网线都拉直。求最少需要一次性购买多长的网线。(说白了,就是找出 N 的一个排列 P1 P2 P3 ..PN 然后 P1 -> P2 -> P3 -> … -> PN 找出 |P1P2|+|P2P3|+…+|PN-1PN| 长度的最小值)
#include<cstring>#include<cmath>#include<algorithm>#include<iostream>#include<cstdio>using namespace std;const int maxn = 21;int n;double x[maxn], y[maxn];double dist[maxn][maxn];struct Path{ int path[maxn]; Path() { for(int i = 0; i < n; i++) path[i] = i; } Path(const Path& p) { memcpy(path, p.path, sizeof path); swap(path[rand() % n], path[rand() % n]); } double dist() { double ans = 0; { ans += ::dist[path[i - 1]][path[i]]; } return ans; }};bool accept(double delta, double temper){ if(delta <= 0) return true; return rand() <= exp((-delta) / temper) * RAND_MAX;} double solve(){ const double max_temper = 10000; const double dec = 0.999; double temp = max_temper; Path p; while(temp > 0.01) { Path p2(p); if(accept(p2.dist() - p.dist(), temp)) p = p2; temp *= dec; } return p.dist();}int main(){ srand(19260817U); cin >> n; for(int i = 0; i < n; i++) { scanf("%lf%lf", x + i, y + i); } for(int j = i + 1; j < n; j++) { dist[i][i] = 0; for(int j = i + 1; j < n; j++) { dist[i][j] = dist[j][i] = hypot(x[i] - x[j], y[i] - y[j]); } } double ans = 1./0; int T = 155; while(T--) { ans = min(ans, solve()); } printf("%.2lf", ans);}
由于随机化算法有一定不稳定性,这里要多次调用计算过程取最小值。T=155就是外循环次数。
值得注意的是,T=15就可以过80%的数据,T=42可以过完全部数据,此时最大数据运行时间为86ms。这里T取155是保险起见,毕竟时间足够。
上面的代码仍有改进的余地。比如,在solve()函数中,应当把最优解记下来,在返回解时返回记下的那个最优解,免得跳到了某些差解后返回差解。
下面是一张表供大家估算运行时间,左边是“降温系数”,上方是初温与末温的比值,表格内容是大致的迭代次数。
除了记忆上表外,我们还可以通过记录退火次数(将tot初始化为零,每次产生新解时tot++,计算完后看看tot)或者使用计算器计算退火次数。计算后选择一个合适的外循环次数。
除此之外,我们还要根据数据规模,灵活地调整初温、末温与降温系数。一般来说,初温不宜太大,否则会让前几次迭代接受了很差的解,浪费时间;降温系数不宜过大,否则会让算法过早稳定,不能找到最优值;同样,降温系数也不宜太高(更不能大于1,不然温度越来越高),否则可能会超时。
在正式使用中还有些技巧,如每次降温后,做足够多次计算后才再次降温(内循环),这对算法准确性没有太大影响。
除了模拟退火外,还有不少随机化算法。比如遗传算法、蚁群算法,这些算法被称为“元启发算法”,有兴趣的读者可以查阅相关资料。
转自:
http://www.cnblogs.com/CsOH/p/6049117.html
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火,遗传算法
- 模拟退火算法概述
- 模拟退火算法
- 遗传模拟退火算法
- 模拟退火遗传算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 解析模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- POJ
- linux系统中的时间API和函数库
- C语言写cat命令
- css的居中如何实现?
- ubuntu bash 背景色
- 模拟退火算法
- request的get和post参数乱码问题
- java面试整理(二)
- django 用户认证系统 相关资料
- add-two-numbers(单链表相加)
- Apache Shiro 使用手册
- OSI七层协议模型
- python系列笔记一:基本数据类型
- Java虚拟机和Dalvik虚拟机的区别