蚁群算法模拟退火算法遗传算法代码和解决TSP问题

蚁群算法解决TSP问题代码

import numpy as np
import matplotlib.pyplot as plt
import pylab

coordinates = np.array([[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]])  # 城市坐标


def getdistmat(coordinates):
    num = coordinates.shape[0]
    distmat = np.zeros((52, 52))  # 打印一个52行52列的二维数组
    for i in range(num):
        for j in range(i, num):
            distmat[i][j] = distmat[j][i] = np.linalg.norm(coordinates[i] - coordinates[j])
    return distmat  # distmat[i][j] = distmat[j][i]表示城市i和j距离


distmat = getdistmat(coordinates)  # 二维数组,表示城市之间的距离
numant = 40  # 蚂蚁个数
numcity = coordinates.shape[0]  # 城市个数   shape[0]输出二维数组【numpy】的行数。
alpha = 1  # 信息素重要程度因子
beta = 5  # 启发函数重要程度因子
rho = 0.1  # 信息素的挥发速度
Q = 1  # 信息素强度
iter = 0
itermax = 250
etatable = 1.0 / (distmat + np.diag([1e10] * numcity))  # 启发函数矩阵,表示蚂蚁从城市i转移到矩阵j的期望程度
pheromonetable = np.ones((numcity, numcity))  # 信息素矩阵        52行52列的二维数组。元素都是1
pathtable = np.zeros((numant, numcity)).astype(int)  # 路径记录表    40行52列的二维数组,目前都为0
# distmat = getdistmat(coordinates)  # 城市的距离矩阵
lengthaver = np.zeros(itermax)  # 各代(各个循环)路径的平均长度          # 一维数组,itermax个0
lengthbest = np.zeros(itermax)  # 各代及其之前遇到的最佳路径长度    # 一维数组,itermax个0
pathbest = np.zeros((itermax, numcity))  # 各代及其之前遇到的最佳路径长度         # itermax(250)行numcity(52)列的二维矩阵

while iter < itermax:  # 循环0-250次
    # 1、随机产生各个蚂蚁的起点城市
    if numant <= numcity:  # 1.1、城市数比蚂蚁数多
        #  permutation():随机排列序列,生成一个0-52的一维数组,[:numant]去除前numant个分配给pathtable中的第0列
        pathtable[:, 0] = np.random.permutation(range(0, numcity))[:numant]
    else:  # 1.2、蚂蚁数比城市数多,需要补足
        pathtable[:numcity, 0] = np.random.permutation(range(0, numcity))[:]  # 先将城市全部取出,剩下的蚂蚁随机分配
        # 剩下numant - numcity个蚂蚁,将分配给他们的城市数分配在他们的第0列
        pathtable[numcity:, 0] = np.random.permutation(range(0, numcity))[:numant - numcity]
    length = np.zeros(numant)  # 计算各个蚂蚁的路径距离,还未走,都是0.
    # 2、各个蚂蚁进行路径选择
    for i in range(numant):
        visiting = pathtable[i, 0]  # 当前所在的城市,将[i,0]位置的值赋值给visiting
        unvisited = set(range(numcity))  # 未访问的城市,以集合的形式存储{}
        unvisited.remove(visiting)  # 删除元素;利用集合的remove方法删除存储的数据内容
        # 3、循环numcity-1次,访问剩余的numcity-1个城市,循环为一只蚂蚁访问所有城市的过程
        for j in range(1, numcity):
            # 每次用轮盘法选择下一个要访问的城市
            listunvisited = list(unvisited)      # 列表,即为一维数组。
            probtrans = np.zeros(len(listunvisited))   # 创建一个【未被访问城市个数】一维数组,s元素全为0
            for k in range(len(listunvisited)):
                probtrans[k] = np.power(pheromonetable[visiting][listunvisited[k]], alpha) \
                               * np.power(etatable[visiting][listunvisited[k]], beta)
            cumsumprobtrans = (probtrans / sum(probtrans)).cumsum()    # cumsum()将probtrans数组中的值进行累加求和
            cumsumprobtrans -= np.random.rand()
            k = listunvisited[(np.where(cumsumprobtrans > 0)[0])[0]]  # python3中原代码运行bug,类型问题;鉴于此特找到其他方法
            # 通过where()方法寻找矩阵大于0的元素的索引并返回ndarray类型,然后接着载使用[0]提取其中的元素,用作listunvisited列表中
            # 元素的提取(也就是下一轮选的城市)
            pathtable[i, j] = k  # 添加到路径表中(也就是蚂蚁走过的路径),第i号蚂蚁第j步走的城市。
            unvisited.remove(k)  # 然后在为访问城市set中remove()删除掉该城市
            length[i] += distmat[visiting][k]    # 当前所在城市visiting到城市k的距离,length[]用于存储各个蚂蚁走的路径长度,一维数组。
            visiting = k
        length[i] += distmat[visiting][pathtable[i, 0]]  # 蚂蚁的路径距离包括最后一个城市和第一个城市的距离  TSP问题,访问所有城市后又回到了原点
        # 包含所有蚂蚁的一个迭代结束后,统计本次迭代的若干统计参数
    # 4、从当前循环中找出最小路径和最小路径长度并保存
    lengthaver[iter] = length.mean()   # 各代(各个循环)路径的平均长度
    if iter == 0:
        lengthbest[iter] = length.min()                      # length[]记录的是当前循环,每个蚂蚁走出的路径长度
        pathbest[iter] = pathtable[length.argmin()].copy()   # length.argmin()显示length[]中最小值的下标
    else:
        if length.min() > lengthbest[iter - 1]:              # 当前循环中的最小路径不是最优值
            lengthbest[iter] = lengthbest[iter - 1]
            pathbest[iter] = pathbest[iter - 1].copy()
        else:
            lengthbest[iter] = length.min()
            pathbest[iter] = pathtable[length.argmin()].copy()
    # 5、更新信息素
    changepheromonetable = np.zeros((numcity, numcity))
    for i in range(numant):
        for j in range(numcity - 1):
            # 更新蚂蚁i从城市j到j+1路径的信息素
            changepheromonetable[pathtable[i, j]][pathtable[i, j + 1]] += Q / distmat[pathtable[i, j]][
                pathtable[i, j + 1]]  # 计算信息素增量
        # 最后一个城市到第一个城市途径的信息素增量
        changepheromonetable[pathtable[i, j + 1]][pathtable[i, 0]] += Q / distmat[pathtable[i, j + 1]][pathtable[i, 0]]
    # 带入计算信息素公式,更新完毕,本次循环结束
    pheromonetable = (1 - rho) * pheromonetable + changepheromonetable  # 计算信息素公式
    iter += 1  # 迭代次数指示器+1
    print("iter:", iter)

# 做出平均路径长度和最优路径长度
fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(12, 10))
axes[0].plot(lengthaver, 'k', marker=u'')
axes[0].set_title('Average Length')
axes[0].set_xlabel(u'iteration')

axes[1].plot(lengthbest, 'k', marker=u'')
axes[1].set_title('Best Length')
axes[1].set_xlabel(u'iteration')
fig.savefig('average_best.png', dpi=500, bbox_inches='tight')
plt.show()

# 作出找到的最优路径图
bestpath = pathbest[-1]   # 每次更新后,pathbest[-1]的最后一行,就是最优路径了
plt.plot(coordinates[:, 0], coordinates[:, 1], 'r.', marker=u'$\cdot$')
plt.xlim([-100, 2000])
plt.ylim([-100, 1500])

for i in range(numcity - 1):
    m = int(bestpath[i])
    n = int(bestpath[i + 1])
    plt.plot([coordinates[m][0], coordinates[n][0]], [coordinates[m][1], coordinates[n][1]], 'k')  # k为黑色
plt.plot([coordinates[int(bestpath[0])][0], coordinates[int(n)][0]],
         [coordinates[int(bestpath[0])][1], coordinates[int(n)][1]], 'b')  # 最后一个城市与第一个城市连线。 b为蓝色
ax = plt.gca()
ax.set_title("Best Path")
ax.set_xlabel('X axis')
ax.set_ylabel('Y_axis')

plt.savefig('best path.png', dpi=500, bbox_inches='tight')
plt.show()


模拟退火算法解决y = x3 - 60x 2 - 4x + 6在定义域[0,100]上的最小值代码

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import math


# define aim function
def aimFunction(x):
    y = x ** 3 - 60 * x ** 2 - 4 * x + 6
    return y


x = [i / 10 for i in range(1000)]
y = [0 for i in range(1000)]
for i in range(1000):
    y[i] = aimFunction(x[i])

plt.plot(x, y)
T = 1000  # initiate temperature
Tmin = 10  # minimum value of terperature
x = np.random.uniform(low=0, high=100)  # initiate x
k = 50  # times of internal circulation
y = 0  # initiate result
t = 0  # time
while T >= Tmin:
    for i in range(k):
        # calculate y
        y = aimFunction(x)
        # generate a new x in the neighboorhood of x by transform function
        xNew = x + np.random.uniform(low=-0.055, high=0.055) * T
        if (0 <= xNew and xNew <= 100):
            yNew = aimFunction(xNew)
            if yNew - y < 0:
                x = xNew
            else:
                # metropolis principle
                p = math.exp(-(yNew - y) / T)
                r = np.random.uniform(low=0, high=1)
                if r < p:
                    x = xNew
    t += 1
    print(t)
    T = 1000 / (1 + t)  #降温函数,也可使用T=0.9T

print(x, aimFunction(x))

模拟退火算法解决TSP问题代码

城市坐标数据:文件名为data.txt

1.304 2.312
3.639 1.315
4.177 2.244
3.712 1.399
3.488 1.535
3.326 1.556
3.238 1.229
4.196 1.044
4.312 0.79
4.386 0.57
3.007 1.97
2.562 1.756
2.788 1.491
2.381 1.676
1.332 0.695
3.715 1.678
3.918 2.179
4.061 2.37
3.78 2.212
3.676 2.578
4.029 2.838
4.263 2.931
3.429 1.908
3.507 2.376
3.394 2.643
3.439 3.201
2.935 3.24
3.14 3.55
2.545 2.357
2.778 2.826
2.37 2.975
3.715 1.678

代码:

# 模拟退火算法求解TSP问题完整代码:
# 31座城市TSP问题
import math
import random
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import sys
from numpy.matlib import rand
from matplotlib.artist import getp
import copy


# 构建初始参考距离矩阵
def getdistance():
    for i in range(n):
        for j in range(n):
            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):
        for j in range(n):
            if distance[i][j] == 0:
                distance[i][j] = sys.maxsize


# 计算总距离
def cacl_best(rou):
    sumdis = 0.0
    for i in range(n - 1):
        sumdis += distance[rou[i]][rou[i + 1]]
    sumdis += distance[rou[n - 1]][rou[0]]
    return sumdis


# 得到新解
def getnewroute(route, time):
    # 如果是偶数次,二变换法
    '''
    注意:数组直接复制是复制地址
    例如, current = route
    想要得到一个新的有同样内容的数组,应该用: current = copy.copy(route)
    '''
    current = copy.copy(route)

    if time % 2 == 0:
        u = random.randint(0, n - 1)
        v = random.randint(0, n - 1)
        temp = current[u]
        current[u] = current[v]
        current[v] = temp
    # 如果是奇数次,三变换法
    else:
        temp2 = random.sample(range(0, n), 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):
    result_x = [0 for col in range(n + 1)]
    result_y = [0 for col in range(n + 1)]

    for i in range(n):
        result_x[i] = city_x[best[i]]
        result_y[i] = city_y[best[i]]
    result_x[n] = result_x[0]
    result_y[n] = result_y[0]
    plt.rcParams['font.sans-serif'] = 'SimHei'  # 设置中文显示
    plt.rcParams['axes.unicode_minus'] = False
    plt.xlim(0, 5)  # 限定横轴的范围
    plt.ylim(0, 4)  # 限定纵轴的范围
    plt.plot(result_x, result_y, marker='>', mec='r', mfc='w', label=u'路线')
    plt.legend()  # 让图例生效
    plt.margins(0)
    plt.subplots_adjust(bottom=0.15)
    for i in range(len(best)):
        plt.text(result_x[i] + 0.05, result_y[i] + 0.05, str(best[i] + 1), color='red')
    plt.xlabel('横坐标')
    plt.ylabel('纵坐标')
    plt.title('轨迹图')
    plt.show()


def print_route(route):
    result_cur_best = []
    for i in route:
        result_cur_best += [i]
    for i in range(len(result_cur_best)):
        result_cur_best[i] += 1
    result_path = result_cur_best
    result_path.append(result_path[0])
    return result_path


def solve():
    # 得到距离矩阵
    getdistance()
    # 得到初始解以及初始距离
    route = random.sample(range(0, n), n)
    total_dis = cacl_best(route)
    print("初始路线:", print_route(route))
    print("初始距离:", total_dis)
    draw(route)
    # 新解
    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)
            new_total_dis = cacl_best(newroute)
            delt = new_total_dis - total_dis
            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("最优路线:", print_route(best))
    print("最优值:", best_total_dis)
    draw(best)


if __name__ == "__main__":
    # 读取31座城市坐标
    coord = []
    with open("data.txt", "r") as lines:
        lines = lines.readlines()
    for line in lines:
        xy = line.split()
        coord.append(xy)
    coord = np.array(coord)
    w, h = coord.shape
    coordinates = np.zeros((w, h), float)
    for i in range(w):
        for j in range(h):
            coordinates[i, j] = float(coord[i, j])
    city_x = coordinates[:, 0]
    city_y = coordinates[:, 1]
    # 城市数量
    n = coordinates.shape[0]
    distance = [[0 for col in range(n)] for raw in range(n)]
    # 初始温度 结束温度
    T0 = 31
    Tend = 1e-8
    # 循环控制常数
    L = 10
    # 温度衰减系数
    a = 0.98
    solve()

遗传算法解决如下题目

题目:

在一个长度为n的数组nums中选择10个元素,使得10个元素的和与原数组的所有元素之和的1/10无限接近。比如n=50,sum(nums)=1000,选择的元素列表answer要满足sum(answer)-100的绝对值小于e,e要尽可能的小。

思路:

  1. 创建包含100个解的随机初始解集(用random.sample(list,number)从list中随机抽取number个元素)
  2. 对解集中每两个解(父体与母体)进行选择交换,问题:如何选择这两个解?那就是选择优秀的交换,用轮盘赌选择法。
  3. 每个解都对应有一个误差和一个适应度,误差越小的解适应度越大(反比例函数)。
    这里的适应度=1/误差。
    归一化,将每个解的适应度除以所有解的适应度之和,归一化后得到选择概率。
    叠加化 a1=a1,a2=a1+a2,a3=a1+a2+a3…,叠加之后每个解的选择概率从0-1依次增长,得到累积概率。
    在0-1中随机选取一个浮点数(如0.4),从选择概率中挑出一个最接近的。
  4. 选择一部分进行交叉重组。
  5. 随机变异,保持种群多样性。
    代码如下:
import random

#1.创建初始解集
def create_answer(numbers_set,n):
    result=[]#存放解集的列表
    for i in range(n):#循环n次,每次创建一个解集(包含10个元素)
        result.append(random.sample(numbers_set,10))#从初始数组中随机抽取10个元素
    return result

#2.选择两个解
#计算误差
def error_level(new_answer,numbers_set):
    error = []#存放适应度的列表
    right_answer = sum(numbers_set)/10#正确答案,也就是原数组所有元素之和的1/10
    for item in new_answer:
        value = abs(right_answer-sum(item))#误差等于每个解与正确答案之差的绝对值
        if value==0:#误差最小是0.1
            error.append(10)#????
        else:
            error.append(1/value)#用反比例函数计算适应度
    return error
#选择两个解
def choice_selected(old_answer,numbers_set):
    result=[]
    error = error_level(old_answer,numbers_set)#调用计算误差函数
    error_one = [item/sum(error) for item in error]#归一化,列表每个元素除以列表总体元素之和,选择概率error_one
    for i in range(1,len(error_one)):#叠加化
        error_one[i] += error_one[i-1]
    for i in range(len(old_answer)//2):#整体选两波
        temp = []#存放父体母体的列表
        for j in range(2):#一波选两个
            rand = random.uniform(0,1)#从0-1中随机选择一个浮点数
            for k in range(len(error_one)):#遍历寻找最接近的答案
                if k==0:
                    if rand<error_one[k]:#如果该浮点数小于第一个数,选择出来放到temp中
                        temp.append(old_answer[k])
                else:
                    if rand>=error_one[k-1] and rand<error_one[k]:#如果该浮点数处在两个数中间,将更大的选择出来放到temp中
                        temp.append(old_answer[k])
        #3.交叉(交换信息)?????
        rand = random.randint(0,6)
        temp_1 = temp[0][:rand]+temp[1][rand:rand+3]+temp[0][rand+3:]#新子体temp1
        temp_2 = temp[1][:rand]+temp[0][rand:rand+3]+temp[1][rand+3:]#新子体temp2
        result.append(temp_1)
        result.append(temp_2)
    return result

#4.随机变异
def variation(old_answer,numbers_set,pro):
    for i in range(len(old_answer)):
        rand = random.uniform(0,1)
        if rand<pro:#如果该随机浮点数小于0.1,就发生变异
            rand_num = random.randint(0,9)#从该解中随便挑出一个元素,发生变异
            old_answer[i] = old_answer[i][:rand_num]+random.sample(numbers_set,1)+old_answer[i][rand_num+1:]
    return old_answer

numbers_set = random.sample(range(0,1000),50)#从0-1000随机抽取50个元素,创建初始nums数组
middle_answer = create_answer(numbers_set,100)#创建包含100个解的随机初始解集,每个解都是随机的10个元素
first_answer = middle_answer[0]#随便找个原始解
great_answer = []#最优解集

for i in range(1000):#训练1000次
    middle_answer = choice_selected(middle_answer,numbers_set)#选择交叉完的middle
    middle_answer = variation(middle_answer,numbers_set,0.1)#变异完的middle
    error = error_level(middle_answer,numbers_set)#生成适应度列表
    index = error.index(max(error))#挑出该群体中适应度最大的下标
    great_answer.append([middle_answer[index],error[index]])

great_answer.sort(key=lambda x:x[1],reverse=True)#从大到小排序
print('正确答案为',sum(numbers_set)/10)
print('原始解为',sum(first_answer))
print('最优解为',great_answer[0][0])
print('最优解的和为',sum(great_answer[0][0]))
print('选择系数为',great_answer[0][1])

遗传算法解决TSP问题代码

#遗传算法求解TSP问题完整代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
import math
import random

# 处理数据

coord = []
with open("data.txt", "r") as lines:
    lines = lines.readlines()
for line in lines:
    xy = line.split()
    coord.append(xy)

coord = np.array(coord)
w, h = coord.shape
coordinates = np.zeros((w, h), float)
for i in range(w):
    for j in range(h):
        coordinates[i, j] = float(coord[i, j])

# print(coordinates)

# 得到距离矩阵

distance = np.zeros((w, w))
for i in range(w):
    for j in range(w):
        distance[i, j] = distance[j, i] = np.linalg.norm(coordinates[i] - coordinates[j])

# 种群数
count = 300

# 进化次数
iter_time = 1000

# 最优选择概率
retain_rate = 0.3  # 适应度前30%可以活下来

# 弱者生存概率
random_select_rate = 0.5

# 变异
mutation_rate = 0.1

# 改良
gailiang_N = 3000


# 适应度
def get_total_distance(x):
    dista = 0
    for i in range(len(x)):
        if i == len(x) - 1:
            dista += distance[x[i]][x[0]]
        else:
            dista += distance[x[i]][x[i + 1]]
    return dista

# 初始种群的改良
def gailiang(x):
    distance = get_total_distance(x)
    gailiang_num = 0
    while gailiang_num < gailiang_N:
        while True:
            a = random.randint(0, len(x) - 1)
            b = random.randint(0, len(x) - 1)
            if a != b:
                break
        new_x = x.copy()
        temp_a = new_x[a]
        new_x[a] = new_x[b]
        new_x[b] = temp_a
        if get_total_distance(new_x) < distance:
            x = new_x.copy()
        gailiang_num += 1


# 自然选择

def nature_select(population):
    grad = [[x, get_total_distance(x)] for x in population]
    grad = [x[0] for x in sorted(grad, key=lambda x: x[1])]
    # 强者
    retain_length = int(retain_rate * len(grad))
    parents = grad[: retain_length]
    # 生存下来的弱者
    for ruozhe in grad[retain_length:]:
        if random.random() < random_select_rate:
            parents.append(ruozhe)
    return parents


# 交叉繁殖
def crossover(parents):
    target_count = count - len(parents)
    children = []
    while len(children) < target_count:
        while True:
            male_index = random.randint(0, len(parents)-1)
            female_index = random.randint(0, len(parents)-1)
            if male_index != female_index:
                break
        male = parents[male_index]
        female = parents[female_index]
        left = random.randint(0, len(male) - 2)
        right = random.randint(left, len(male) - 1)
        gen_male = male[left:right]
        gen_female = female[left:right]
        child_a = []
        child_b = []

        len_ca = 0
        for g in male:
            if len_ca == left:
                child_a.extend(gen_female)
                len_ca += len(gen_female)
            if g not in gen_female:
                child_a.append(g)
                len_ca += 1

        len_cb = 0
        for g in female:
            if len_cb == left:
                child_b.extend(gen_male)
                len_cb += len(gen_male)
            if g not in gen_male:
                child_b.append(g)
                len_cb += 1

        children.append(child_a)
        children.append(child_b)
    return children


# 变异操作
def mutation(children):
    for i in range(len(children)):
        if random.random() < mutation_rate:
            while True:
                u = random.randint(0, len(children[i]) - 1)
                v = random.randint(0, len(children[i]) - 1)
                if u != v:
                    break
            temp_a = children[i][u]
            children[i][u] = children[i][v]
            children[i][v] = temp_a


def get_result(population):
    grad = [[x, get_total_distance(x)] for x in population]
    grad = sorted(grad, key=lambda x: x[1])
    return grad[0][0], grad[0][1]


population = []
# 初始化种群
index = [i for i in range(w)]
for i in range(count):
    x = index.copy()
    random.shuffle(x)
    gailiang(x)
    population.append(x)

distance_list = []
result_cur_best, dist_cur_best = get_result(population)
distance_list.append(dist_cur_best)

i = 0
while i < iter_time:
    # 自然选择
    parents = nature_select(population)

    # 繁殖
    children = crossover(parents)

    # 变异
    mutation(children)

    # 更新
    population = parents + children

    result_cur_best, dist_cur_best = get_result(population)
    distance_list.append(dist_cur_best)
    i = i + 1
    print(result_cur_best)
    print(dist_cur_best)


for i in range(len(result_cur_best)):
    result_cur_best[i] += 1

result_path = result_cur_best
result_path.append(result_path[0])

print(result_path)

# 画图

X = []
Y = []
for index in result_path:
    X.append(coordinates[index-1, 0])
    Y.append(coordinates[index-1, 1])

plt.rcParams['font.sans-serif'] = 'SimHei'  # 设置中文显示
plt.rcParams['axes.unicode_minus'] = False
plt.figure(1)
plt.plot(X, Y, '-o')
for i in range(len(X)):
    plt.text(X[i] + 0.05, Y[i] + 0.05, str(result_path[i]), color='red')
plt.xlabel('横坐标')
plt.ylabel('纵坐标')
plt.title('轨迹图')

plt.figure(2)
plt.plot(np.array(distance_list))
plt.title('优化过程')
plt.ylabel('最优值')
plt.xlabel('代数({}->{})'.format(0, iter_time))
plt.show()

你可能感兴趣的:(算法,模拟退火算法,numpy)