Skip to content
Gyunseo's Blog
Go back

Brute Force Traveling Salesman Problem

Suggest Changes

Table of contents

Open Table of contents

python 코드

import time, unittest
from itertools import permutations


def get_min_tsp_path(graph, starting_vertex):
    tsp_path_candidates = [*permutations(range(2, 6), 4)]
    min_tsp_weight_sum = 1000000
    min_tsp_path = tsp_path_candidates[0]

    def get_next_vertex_weight_for_cur_vertex(cur_vertex, next_vertex):
        for nv_candidate, w in graph[cur_vertex]:
            if nv_candidate == next_vertex:
                return w

    # 외판원 순회 경로를 순열로 구한 후, 각 경로의 가중치 합을 구한다.
    # 그 중 가장 작은 가중치 합을 구한다.
    for candidate_path in tsp_path_candidates:
        cv = starting_vertex
        tsp_weight_sum = 0
        for nv in candidate_path:
            tsp_weight_sum += get_next_vertex_weight_for_cur_vertex(cv, nv)
            cv = nv
        tsp_weight_sum += get_next_vertex_weight_for_cur_vertex(cv, starting_vertex)
        if tsp_weight_sum < min_tsp_weight_sum:
            min_tsp_weight_sum = tsp_weight_sum
            min_tsp_path = candidate_path

    return ((starting_vertex, *min_tsp_path, starting_vertex), min_tsp_weight_sum)


class TSPTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        # input.txt를 읽기
        cls.graph = [
            [],  # 정점 0은 사용하지 않으며, 1부터 시작한다.
            [(2, 2), (3, 3), (4, 2), (5, 3)],  # 정점 1에서 다른 정점으로 가는 가중치
            [(1, 2), (3, 3), (4, 4), (5, 1)],  # 정점 2에서 다른 정점으로 가는 가중치
            [(1, 3), (2, 3), (4, 2), (5, 4)],  # 정점 3에서 다른 정점으로 가는 가중치
            [(1, 2), (2, 4), (3, 2), (5, 5)],  # 정점 4에서 다른 정점으로 가는 가중치
            [(1, 3), (2, 1), (3, 4), (4, 5)],  # 정점 5에서 다른 정점으로 가는 가중치
        ]
        cls.starting_vertex = 1
        print("Brute Force TSP 테스트 시작")

    @classmethod
    def tearDownClass(cls) -> None:
        print("\nBrute Force TSP 테스트 종료\n")
        print(
            f"최소 비용 외판원 순회 경로: {get_min_tsp_path(TSPTest.graph, TSPTest.starting_vertex)[0]}"
        )
        print(
            f"최소 비용 외판원 순회 경로 가중치 합: {get_min_tsp_path(TSPTest.graph, TSPTest.starting_vertex)[1]}"
        )

    def setUp(self) -> None:
        self.start_time = time.time()

    def tearDown(self) -> None:
        self.end_time = time.time()
        print(
            f"\nget_min_tsp_path 함수 소요 시간: {self.test_function_end_time - self.test_function_start_time:4f}s"
        )
        print(f"테스트 자체의 소요 시간: {self.end_time - self.start_time:4f}s")

    def test_tsp(self):
        self.test_function_start_time = time.time()
        res = get_min_tsp_path(TSPTest.graph, TSPTest.starting_vertex)
        self.test_function_end_time = time.time()
        self.assertEqual(res, ((1, 2, 5, 3, 4, 1), 11))


if __name__ == "__main__":
    unittest.main(verbosity=2)

How to Run

python version: 3.11.6

Run main.py

pip install pipenv
pipenv --python 3.11.6
pipenv run python3 main.py

Input

graph = [
            [],  # 정점 0은 사용하지 않으며, 1부터 시작한다.
            [(2, 2), (3, 3), (4, 2), (5, 3)],  # 정점 1에서 다른 정점으로 가는 가중치
            [(1, 2), (3, 3), (4, 4), (5, 1)],  # 정점 2에서 다른 정점으로 가는 가중치
            [(1, 3), (2, 3), (4, 2), (5, 4)],  # 정점 3에서 다른 정점으로 가는 가중치
            [(1, 2), (2, 4), (3, 2), (5, 5)],  # 정점 4에서 다른 정점으로 가는 가중치
            [(1, 3), (2, 1), (3, 4), (4, 5)],  # 정점 5에서 다른 정점으로 가는 가중치
        ]

Output

Loading .env environment variables...
Brute Force TSP 테스트 시작
test_tsp (__main__.TSPTest.test_tsp) ...
get_min_tsp_path 함수 소요 시간: 0.000024s
테스트 자체의 소요 시간: 0.000039s
ok

Brute Force TSP 테스트 종료

최소 비용 외판원 순회 경로: (1, 2, 5, 3, 4, 1)
최소 비용 외판원 순회 경로 가중치 합: 11

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

Execution Image


Suggest Changes
Share this post on:

Previous Post
Brute Force Knapsack Problem
Next Post
Brute Force String Matching Algorithm