0

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

0 Answers0