数学建模——模拟退火算法

数学建模——模拟退火算法解决TSP问题

1 模拟退火简介

热能变化

热能上升以一定的概率去调整,直到静止状态
在这里插入图片描述
在这里插入图片描述

2 路径数据及程序

2.1数据 verify_order_position_10.csv

在这里插入图片描述

1476786	43.013425	-81.2768629
1476794	42.9923696 -81.2742454
1476933	42.983249	-81.2848146
1477049	43.0104333 -81.2735103
1477050	43.0104333 -81.2735103
1477051	43.0104333 -81.2735103
1477093	43.0180602 -81.281657
1477110	42.9861887 -81.2970252
1477119	42.9503241 -81.2864436
1477553	43.013425	-81.2768629

2.2程序

# 模拟退火算法————解TSP问题
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 20 18:41:02 2020
@author: andrew
"""
import pandas as pd
import math
import random
import matplotlib.pyplot as plt
import sys
import copy
import time

#初始温度 结束温度
T0 = 30
Tend = 1e-8
#循环控制常数
L = 50
#温度衰减系数
a = 0.98


def init_dis_matrix(length):
    # 初始化距离矩阵
    distance_matrix = [[0 for col in range(length)] for raw in range(length)]
    return distance_matrix
    
    
def load_position(file_name):
    # 读入城市的位置
    data = pd.read_csv(file_name,names=['index','lat','lon'])
    city_x = data['lat'].tolist()
    city_y = data['lon'].tolist()
    return city_x,city_y
#构建初始参考距离矩阵
def getdistance(city_x,city_y,n_len,distance):
    for i in range(n_len):
        for j in range(n_len):
            x = pow(city_x[i] - city_x[j], 2)
            y = pow(city_y[i] - city_y[j], 2)
            distance[i][j] = pow(x + y, 0.5)
    for i in range(n_len):
        for j in range(n_len):
            if distance[i][j] == 0:
                distance[i][j] = sys.maxsize

#计算总距离
def cacl_best(rou,n_len,distence):
    sumdis = 0.0
    for i in range(n_len-1):
        sumdis += distence[rou[i]][rou[i+1]]
    sumdis += distence[rou[n_len-1]][rou[0]]     
    return sumdis
def getnewroute(route, time,n_len):
    # 得到新的路径
    # 如果是偶数次,二变换法
    current = copy.copy(route)
    if time % 2 == 0:
        u = random.randint(0, n_len-1)
        v = random.randint(0, n_len-1)
        temp = current[u]
        current[u] = current[v]
        current[v] = temp
    #如果是奇数次,三变换法 
    else:
        temp2 = random.sample(range(0, n_len), 3)
        temp2.sort()
        u = temp2[0]
        v = temp2[1]
        w = temp2[2]
        w1 = w + 1
        temp3 = [0 for col in range(v - u + 1)]
        j =0
        for i in range(u, v + 1):
            temp3[j] = current[i]
            j += 1
        for i2 in range(v + 1, w + 1):
            current[i2 - (v-u+1)] = current[i2]
        w = w - (v-u+1)
        j = 0
        for i3 in range(w+1, w1):
            current[i3] = temp3[j]
            j += 1
    return current
    
def draw(best,city_x,city_y,n_len):
    # 画出路径图
    result_x = [0 for col in range(n_len+1)]
    result_y = [0 for col in range(n_len+1)]
    for i in range(n_len):
        result_x[i] = city_x[best[i]]
        result_y[i] = city_y[best[i]]
    result_x[n_len] = result_x[0]
    result_y[n_len] = result_y[0]
    print(result_x)
    print(result_y)

    # 将地点坐标恢复到以前的数值
    result_x_new = [x/1000 for x in result_x]
    result_y_new = [y/1000 for y in result_y]
    plt.xlim(42.9, 43.1)  # 限定横轴的范围
    plt.ylim(-81.26, -81.30)  # 限定纵轴的范围

    plt.plot(result_x_new, result_y_new, marker='>', mec='r', mfc='w',label=u'Route')
    plt.legend()  # 让图例生效
    plt.margins(0)
    plt.subplots_adjust(bottom=0.15)
    plt.xlabel(u"x")  # X轴标签
    plt.ylabel(u"y")  # Y轴标签
    plt.title("route plan")  # 标题
    plt.show()
    plt.close(0)
    
def solve(file_name):
    city_x,city_y = load_position(file_name)  # list
    n_len = len(city_x)  # 10
    city_x = [x*1000 for x in city_x]
    city_y = [x*1000 for x in city_y]
    distence = init_dis_matrix(n_len)   # 初始化距离矩阵
    getdistance(city_x,city_y,n_len,distence)   #得到距离矩阵
    route = random.sample(range(0, n_len), n_len)  # 初始路径
    total_dis = cacl_best(route,n_len,distence)   # 初始距离
    print("初始路线:", route)
    print("初始距离:", total_dis)
    #新解
    newroute = []
    new_total_dis = 0.0
    best = route
    best_total_dis = total_dis
    t = T0  # 令温度为初始温度
    while True:
        if t <= Tend:
            break
        for rt2 in range(L):
            newroute = getnewroute(route, rt2,n_len)  # 得到新的路径
            new_total_dis = cacl_best(newroute,n_len,distence)  # 得到新的路径距离
            delt = new_total_dis - total_dis  # 新旧路径差值
            # 差值小于0则将最好路径及最好路径总长重新赋值
            if delt <= 0:
                route = newroute
                total_dis = new_total_dis
                if best_total_dis > new_total_dis:
                    best = newroute
                    best_total_dis = new_total_dis
            # 差值大于零则变换到步骤二,随意后的状态采纳概率值是否重新赋值
            elif delt > 0:
                p = math.exp(-delt / t)
                ranp = random.uniform(0, 1)
                if ranp < p:
                    route = newroute
                    total_dis = new_total_dis
        t = t * a  # 温度下降
    print("现在温度为:", t)
    print("最佳路线:", best)
    print("最佳距离:", best_total_dis)  
    draw(best,city_x,city_y,n_len)
    return best
if __name__=="__main__":
    start = time.time()
    best = solve('verify_order_postion_20.csv')
    end = time.time()
    print('time : ',end-start)
    print(best)

3 程序运行结果

在这里插入图片描述
最佳路径
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值