Имитация алгоритма отжига для решения задачи коммивояжера в Python - PullRequest
0 голосов
/ 05 марта 2019

Итак, я пытаюсь решить проблему коммивояжера с помощью имитации отжига. Мне дана матрица 100x100, которая содержит расстояния между каждым городом, например, [0] [0] будет содержать 0, поскольку расстояния между первым городом и самим собой равны 0, [0] [1] содержит расстояние между первым и второй город и тд.

Моя проблема в том, что написанный мной код не минимизирует пройденное расстояние, он застревает в диапазоне чисел и никогда не сводит к минимуму правильное сведение, пока температура не достигнет 0. Я попытался сделать ту же проблему с алгоритмом восхождения на холм и он работал нормально, но я не могу заставить его работать с имитацией отжига. Может кто-нибудь помочь мне понять, что я делаю не так?

Mat = distancesFromCoords() #returns the 100x100 matrix with distances
T = 10000 #temperature
Alpha = 0.98 #decreasing factor
X = [i for i in range(99)] #random initial tour
random.shuffle(X)
X.append(X[0])    

while T > 0.01:
    Z = nuevoZ(X,Mat) #Best current solution
    Xp = copy.deepcopy(X)          
    a = random.sample(range(1,98),2)
    Xp[a[0]], Xp[a[1]] = Xp[a[1]],Xp[a[0]]   
    Zp = nuevoZ(Xp,Mat)  #Probable better solution

    decimal.setcontext(decimal.Context(prec=5))
    deltaZ = Zp - Z
    Prob = decimal.Decimal(-deltaZ/T).exp()

    print("probabilidad: ", Prob)
    print("Temperatura: ",T)
    print("Z: ",Z)
    print("Zp: ",Zp)
    print("\n")

    if Zp < Z:
        X = Xp
        T = T*Alpha
    else:
        num = randint(0,1)
        if num<Prob:
            X = copy.copy(Xp)
            T = T*Alpha

функций, используемых в алгоритме:

def nuevoZ(X, Mat):
Z = 0
for i in range(len(X)-1):
    Z = Z + Mat[X[i]][X[i+1]] 
return Z  #returns a new solution given the tour X and the City Matrix.


def distancesFromCoords():  #gets the matrix from a text file.
f = open('kroA100.tsp')
data = [line.replace("\n","").split(" ")[1:] for line in f.readlines()[6:106]]
coords =  list(map(lambda x: [float(x[0]),float(x[1])], data))
distances = []
for i in range(len(coords)):
    row = []
    for j in range(len(coords)):
        row.append(math.sqrt((coords[i][0]-coords[j][0])**2 + (coords[i][1]-coords[j][1])**2))
    distances.append(row)
return distances
...