I am doing the problem "Deliverer's Path" (TSP) using Simulated annealing algorithm. The problem is that after solving, the evaluation difference has reached a good value, but the optimal state is not correct.
import numpy as np
import pandas as pd
from random import randint, random, shuffle
from typing import Type
import math
import matplotlib.pyplot as plt
class Coordinate():
def __init__(self, x, y):
self.x = x
self.y = y
def get_distance(a, b):
return np.sqrt(np.abs(a.x - b.x) + np.abs(a.y - b.y))
def get_total_distance(coords):
dist = 0
for first, second in zip(coords[:-1], coords[1:]):
dist += Coordinate.get_distance(first, second)
dist += Coordinate.get_distance(coords[0], coords[-1])
return dist
class Problem:
def __init__(self):
self.goal = None
def get_state(self): pass
def cost(self, coords): pass
class TSP(Problem):
def __init__(self, coords):
Problem.__init__(self)
self.coords = coords
def get_state(self):
Problem.get_state(self)
return list(self.coords)
def cost(self, coords):
Problem.cost(self, coords)
dist = Coordinate.get_total_distance(coords)
return dist
def draw_route(self, coords):
fig = plt.figure(figsize=(10, 10))
ax1 = fig.add_subplot(1, 1, 1)
for fisrt, second in zip(coords[:-1], coords[1:]):
ax1.plot([fisrt.x, second.x], [fisrt.y, second.y], 'b')
ax1.plot([coords[0].x, coords[-1].x], [coords[0].y, coords[-1].y], 'b')
for c in coords:
ax1.plot(c.x, c.y, 'ro')
plt.show()
dict_city = {(2, 3): 'A', (4, 5): 'B', (8, 7): 'C', (12, 17): 'D',
(18, 8): 'E', (14, 3): 'F', (17, 8): 'G', (14, 12): 'H',
(4, 15): 'I', (17, 10): 'J'
}
coords = []
for key in dict_city:
temp = list(key)
coords.append(Coordinate(temp[0], temp[1]))
tsp = TSP(coords)
tsp.draw_route(tsp.get_state())
cost = tsp.cost(tsp.get_state())
print('cost = ', cost)
class Node:
def __init__(self, state, cost):
self.state = state
self.cost = cost
class Problem_solver:
def __init__(self): pass
def train(self, problem: Type[Problem]): pass
def solve(self): pass
class Bfs_solver(Problem_solver):
def __init__(self):
Problem_solver.__init__(self)
def train(self, problem: Type[Problem]):
Problem_solver.train(self, problem)
self.problem = problem
def solve(self):
Problem_solver.solve(self)
node = self.__simulated_annealing()
return node
def __simulated_annealing(self):
initial_state = self.problem.get_state()
initial_node = Node(initial_state, self.cost_function(initial_state))
current_node = initial_node
self.Tmax = 30
# Đặt nhiệt độ bạn đầu
temperature = self.Tmax
step = 1
while temperature > 0.001:
# cập nhật nhiệt độ
temperature = self.temperature_function(step)
print(step, 'cost = ', current_node.cost,
'temperature = ', temperature)
# tại mỗi mức nhiệt độ thực hiện lại 100 lần để tăng xác suất chọn được phương án tối ưu nhất
for i in range(100):
# Chọn ngẫu nhiên neighbor
neighbor_state = self.neighbor_function(current_node.state)
neighbor_node = Node(
neighbor_state, self.cost_function(neighbor_state))
# Tính toán các thông số
delta = neighbor_node.cost - current_node.cost
if delta < 0:
current_node = neighbor_node
elif random() < math.exp(-delta / temperature):
current_node = neighbor_node
step += 1
return current_node
def neighbor_function(self, coords: list):
neighbor = coords
shuffle(neighbor)
return list(neighbor)
def cost_function(self, coords: list):
cost = self.problem.cost(coords)
return cost
def temperature_function(self, step):
return self.Tmax*(0.99**step)
solver = Bfs_solver()
solver.train(tsp)
solution = solver.solve()
print('best cost = ', solution.cost)
tsp.draw_route(solution.state)
print('cost của solution.state', tsp.cost(solution.state))
I try to find the error and realize it is wrong in SA function the optimal state returned by the function does not correspond to the optimal cost of the function returned.however I don't know how to solve it