zoukankan      html  css  js  c++  java
  • 模拟退火求TSP问题的近似解

    玻尔兹曼分布

    [P_T(X = i) = frac{e^{-frac{E(i)}{KT}}}{sum_{jin S}e^{-frac{E(j)}{KT}}}\ \E(i) 表示在i状态下的温度 \S表示所有的状态 \K表示玻尔兹曼常数 \T为材料当前的温度 ]

    思路介绍

    如果从高温开始非常缓慢的降温,那么粒子可以在每个温度达到平衡

    当系统完全冷却的时候,最终形成一个低能状态下的晶体

    Metrppolis算法

    • 当材料处于温度 T 时, 如果要进行状态 i->j的转换需要满足如下条件之一
      1. E(i)<E(j)
      2. 如果 E(j)>E(i) 那么状态转换接受的概率是 (e^{frac{e(i)-e(j)}{KT}})

    作用:

    ​ 求组合优化问题,最小值问题等

    最终当T降到0时,Xi满足如下分布

    [P_i^*=left{egin{aligned} frac{1}{mid{S_{min}}mid},& &x_iquadinquad S_{min}\ 0, & &其他 end{aligned} ight. ]

    并且可知:

    [sum_{x_iin S_{min}}P_iquad=quad1 ]


    应用举例

    解旅行商问题

    • 目标函数:

      ​ 总的距离

    • 可行解:

      所有坐标点的全排列

    • 变换过程

      将初始的排列的某一段反向

    代码

    import matplotlib.pyplot as plt
    import numpy as np
    import random
    import math
    
    a = np.random.rand();
    point = np.random.rand(100,2)*100
    
    
    #  计算每个点到每个点的距离
    dist = np.zeros((100, 100), dtype=float)
    for i in range(100):
    	for j in range(100):
    		dist[i][j] = math.sqrt((point[i][0]-point[j][0])**2 + (point[i][1]-point[j][1])**2)
    
    # 多次随机试探求得一个相对较好的初始解
    path = []
    init = list(range(1,100))
    length = float("inf")
    for j in range(1000):
    	random.shuffle(init)
    	temp_len = 0
    	for i in range(1,99):
    		temp_len += dist[init[i-1]][init[i]]
    	temp_len += dist[0][init[0]]+dist[init[98]][0]
    	if temp_len<length:
    		path = init[:]  #  深拷贝列表
    		length = temp_len
    
    
    print("init path:{}".format(path))
    print("init length:{}".format(length))
    cur_path = [0]
    cur_path.extend(path)
    cur_path.append(0)
    
    
    
    e = 0.1**30 # 提前跳出的条件
    L = 20000  # 迭代的次数
    at = 0.999 # 降温速度
    T = 1   #  初始的温度,忽略了K,也就是取K等于1
    for t in range(L):
    	# 生成一个新的路径
    	# 随机数取得中间的一段, 方法是把这一段路径反向, 这样计算距离更方便
    	c1, c2 = random.randint(1,99), random.randint(1,99)
    	if c1>c2:
    		c1, c2 = c2, c1
    	df = dist[cur_path[c1]][cur_path[c2+1]]+dist[cur_path[c1-1]][cur_path[c2]]-dist[cur_path[c1-1]][cur_path[c1]]-dist[cur_path[c2]][cur_path[c2+1]]
    	if df<0 or math.exp(-df/T)>random.random():
    		length += df
    		while c1<c2:
    			cur_path[c1], cur_path[c2] = cur_path[c2],cur_path[c1]
    			c1 += 1
    			c2 -= 1
    		T = T*at;  # 每当有接受的, 就进行降温
    		if T<e:
    			break;
    print(cur_path)
    
    print(point[cur_path, 0])
    print(point[cur_path, 1])
    
    plt.plot(point[cur_path, 0], point[cur_path, 1], '-o')
    plt.plot(point[0][0], point[0][1], 'ro')
    plt.title("Total length of travel: {}".format(length))
    plt.show()
    print(length)![](C:Users82504AppDataRoamingTypora	ypora-user-imagesimage-20200721093032306.png)
    


  • 相关阅读:
    PHP危险函数总结学习
    2019网络与信息安全专项赛题解
    BUUCTF平台-web-边刷边记录-2
    SpringCloud-Config 分布式配置中心
    SpringCloud-Gateway 网关路由、断言、过滤
    SpringCloud-Ribbon负载均衡机制、手写轮询算法
    服务注册与发现-Eureka、Consul、Zookeeper的区别
    Docker 私有仓库搭建
    微服务熔断限流Hystrix之流聚合
    微服务熔断限流Hystrix之Dashboard
  • 原文地址:https://www.cnblogs.com/Crossea/p/13353225.html
Copyright © 2011-2022 走看看