使用模拟退火的旅行商问题[Python]

时间:2018-12-07 03:43:58

标签: python traveling-salesman simulated-annealing

下面给出的是我用python用模拟退火技术解决旅行商问题的程序。我无法使Hopfield网络收敛并获得适当的游览矩阵。我无法弄清楚问题出在哪里或我做错了什么。是我写错的任何参数值或任何方程式。任何见识和帮助将不胜感激。非常感谢!我已经呆了两天,无法弄清楚哪里出了问题。

可能出现问题的地方

  1. 我注意到增量C(成本变化)过高。因此,Ai的值始终为0.5。这就是为什么counter1和counter2的值大致相同的原因。

  2. 也许罚款计算不正确,但是我检查了几次数学却没有发现任何错误。

  3. 温度值

    import time
    startTime = time.time()
    import random
    import numpy as np
    import math
    import copy
    
    # Function to caluculate penalty. Returns total penalty and the penalty matrix
    def calcPenalty(tour, distance):
        cost = 0
        penalty = np.zeros([10, 10])
        for i in range(len(tour)):
            for j in range(len(tour)):
                # Penalty to skip a city
                if np.sum(tour[i, :]) == 0:
                    penalty[i][j] = penalty[i][j] + ((A/2)*(N - (tour[i, :].dot(weight[i, :].T))))
                # Penalty to skip a day
                if np.sum(tour[:, j]) == 0:
                    penalty[i][j] = penalty[i][j] + ((B/2)*(N - (tour[:, j].dot(weight[:, j].T))))
                # Penalty for visiting multiple city
                if np.sum(tour[i, :]) > 1:
                    penalty[i][j] = penalty[i][j] + (tour[i, :].dot(weight[i, :]) - 1)*C/2
                # Penalty for visiting same city multiple days
                if np.sum(tour[:, j]) > 1:
                    penalty[i][j] = penalty[i][j] + (tour[:, j].dot(weight[:, j]) - 1)*D/2
                # Distance penalty
                for k in range(10):
                    if i == k:
                        penalty[i][j] += 0
                    else:
                        if j == 0:
                            penalty[i][j] = penalty[i][j] + (distance[i][k]*tour[i][j] * tour[k][j+1])*E/2
                        elif j == 9:
                            penalty[i][j] = penalty[i][j] + (distance[i][k]*tour[i][j] * tour[k][j-1])*E/2
                        else:
                            penalty[i][j] = penalty[i][j] + (distance[i][k]*tour[i][j] * (tour[k][j+1] + tour[k][j-1]))*E/2
        costMatrix = penalty
        cost = np.sum(penalty)
        return cost, costMatrix
    
    # Defining Input
    distance = np.array([[0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
                     [118,   0,   0,   0,   0,   0,   0,   0,   0,   0],
                     [146, 119,   0,   0,   0,   0,   0,   0,   0,   0],
                     [39, 116,  68,   0,   0,   0,   0,   0,   0,   0],
                     [53,  65, 104,   9,   0,   0,   0,   0,   0,   0],
                     [85,  65, 148,  15,  31,   0,   0,   0,   0,   0],
                     [23,  16,  98,  20,  29,  55,   0,   0,   0,   0],
                     [146,  70, 146,  90, 110,   5,  42,   0,   0,   0],
                     [47,  62,   9, 103,  84,  39,  78,  14,   0,   0],
                     [47, 100,  19, 107,  43,  27,  87,   3, 124,   0]])
    
    tourMatrix = np.array([[0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
             [0, 1, 1, 1, 0, 1, 1, 0, 0, 0],
             [0, 1, 1, 0, 0, 0, 1, 0, 0, 0],
             [0, 1, 0, 1, 1, 0, 1, 0, 0, 1],
             [1, 0, 0, 1, 0, 1, 0, 1, 1, 1],
             [1, 0, 1, 0, 0, 1, 1, 1, 0, 0],
             [0, 1, 0, 0, 0, 1, 0, 0, 1, 1],
             [0, 0, 1, 1, 1, 0, 1, 1, 1, 1],
             [1, 1, 0, 1, 0, 0, 1, 1, 0, 1],
             [0, 0, 0, 0, 0, 1, 1, 0, 1, 1]])
    
    tour = np.array([[0, 0, 1, 1, 0, 0, 0, 1, 1, 1],
                [0, 1, 1, 1, 0, 1, 1, 0, 0, 0],
                [0, 1, 1, 0, 0, 0, 1, 0, 0, 0],
                [0, 1, 0, 1, 1, 0, 1, 0, 0, 1],
                [1, 0, 0, 1, 0, 1, 0, 1, 1, 1],
                [1, 0, 1, 0, 0, 1, 1, 1, 0, 0],
                [0, 1, 0, 0, 0, 1, 0, 0, 1, 1],
                [0, 0, 1, 1, 1, 0, 1, 1, 1, 1],
                [1, 1, 0, 1, 0, 0, 1, 1, 0, 1],
                [0, 0, 0, 0, 0, 1, 1, 0, 1, 1]])
    print("HERE")
    print(tourMatrix)
    weight = np.ones([10, 10])
    alpha = 0.995
    temperature = 100
    # weights
    A=300
    B=300
    C=200
    D=200
    E=300
    N = 13
    counter1 = 0
    counter2 = 0
    
    print("------------------------------------------------------------------------------")
    print("Initial Tour Matrix is:")
    print(tour)
    print("------------------------------------------------------------------------------")
    print("Initial Distance Matrix is:")
    print(distance)
    print("------------------------------------------------------------------------------")
    
    for index in range(10000):
        # Get the Initial Cost
        initialCost, initialCostMatrix = calcPenalty(tour, distance)
        # print("Initial cost is:")
        # print(initialCost)
        # Flip a bit and check for cost
        rx = np.random.randint(10)
        ry = np.random.randint(10)
        tour[rx][ry] = 0 if tour[rx][ry] else 1
        # Calculate the cost after flipping a bit
        intCost, intCostMatrix = calcPenalty(tour, distance)
        # print("Cost after flipping bit is:")
        # print(intCost)
        # print("------------------------------------------------------------------------------")
    
    k = math.exp( - abs( intCost - initialCost ) / temperature  )    
    Ai = 1/(1 + math.exp(k))
    # print(Ai,k)
    if Ai <= np.random.rand(1):
        tour[rx][ry] = 0 if tour[rx][ry] else 1
        counter1+=1
    else:
        counter2+=1
    temperature *= alpha
    
    print("Number of 1's initially:")
    print(tourMatrix)
    print(np.sum(tourMatrix))
    print()
    print(tour)
    print()
    print("Number of 1's in the end:")
    print(np.sum(tour))
    print()
    print("Time it took to run the code:")
    print(time.time() - startTime)
    print()
    print(counter1)
    print(counter2)
    

0 个答案:

没有答案