이 영역을 누르면 첫 페이지로 이동
Arc 블로그의 첫 페이지로 이동

Arc

페이지 맨 위로 올라가기

Arc

[Algorithm] 외판원 순회 문제(Traveling Salesman Problem)

  • 2023.04.06 15:21
  • Algorithm/Algorithm
글 작성자: SeoArc

외판원 순회 문제(TSP)

외판원 순회 문제(TSP)는 조합 최적화 문제 일종으로, NP-난해 집합에 속하기 때문에 계산 이론에서 해를 구하기 어려운 문제의 대표적인 사례로 많이 다룬다. 즉, 아직까지 다항 시간에 해결할 수 있는 해결책을 못찾았으며 해결하지 못한다는 것도 증명하지 못했다.

 

외판원 문제의 내용은 다음과 같다.

예를 들어, 어떤 외판원이 n개의 도시를 방문할 계획을 갖고 있다고 하자.

각 도시는 다른 모든 도시와 도로로 연결되어 있다. 출장 비용을 최소로 줄이기 위해 외판원이 출발하는 도시에서 각 도시를 한 번씩만 방문하고 다시 출발한 도시로 돌아오는 가장 최소 비용의 경로를 찾고자 할 때, 어떻게 찾을 수 있을까?

 

만약 20개의 도시가 있을 때 정답을 찾기 위해 다녀야 하는 총 경로 수는 20! = 2,432,902,008,176,640,000이다

 

 

풀이

다음 코드는 [baekjoon] 2098: 외판원 순회을 기준으로 작성하였다.

 

동적 계획법(DP) 풀이

DP를 이용하면 지수 시간에 풀 수 있다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class TSP {

    private static int n;
    private static int[][] map;
    private static int[][] dp;
    private static final int INF = 11_000_000;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        n = Integer.parseInt(br.readLine());
        map = new int[n][n];
        dp = new int[n][(1 << n) - 1];

        for (int i = 0; i < n; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            for (int j = 0; j < n; j++) {
                map[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for (int i = 0; i < n; i++) {
            Arrays.fill(dp[i], -1);
        }

        System.out.println(search(0, 1));
    }

    /**
     *
     * @param city: 현재 위치한 도시 인덱스
     * @param visitBitMask: 지금까지 방문한 도시 이진수
     * @return
     */
    public static int search(int city, int visitBitMask) {
        // 모든 도시를 방문했다면
        if (visitBitMask == (1 << n) - 1) {
            if (map[city][0] > 0) {
                return map[city][0]; // 현재 도시 -> 0번째(시작) 도시 이동 거리
            }
            return INF;
        }

        if (dp[city][visitBitMask] != -1) { // dp 값이 존재하는 경우
            return dp[city][visitBitMask];
        }

        dp[city][visitBitMask] = INF;
        for (int i = 0; i < n; i++) { // 현재 도시(city)에서 각 i의 도시로 이동한 경우에 대해 dfs 수행
            if (i == city) {
                continue;
            }

            if ((visitBitMask & (1 << i)) == 0 && map[city][i] > 0) { // 방문하지 않았던 도시
                // 다음 도시까지 거리와 최소거리 비교
                dp[city][visitBitMask] = Math.min(dp[city][visitBitMask], search(i, visitBitMask | (1 << i)) + map[city][i]);
            }
        }
        return dp[city][visitBitMask];
    }
}

 

저작자표시 (새창열림)

'Algorithm > Algorithm' 카테고리의 다른 글

[Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)  (0) 2023.04.04
[Algorithm] 벨만-포드 알고리즘(Bellman-Ford Algorithm)  (0) 2023.03.30
[Algorithm] 페르마의 소정리  (1) 2023.03.18
[Algorithm] 플로이드-워셜(Floyd-Warshall)  (0) 2023.03.12
[Algorithm] 상계/하계(Upper Bound/Lower Bound)  (1) 2023.03.11

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)

    [Algorithm] 보이어-무어 알고리즘(Boyer-Moore Algorithm)

    2023.04.04
  • [Algorithm] 벨만-포드 알고리즘(Bellman-Ford Algorithm)

    [Algorithm] 벨만-포드 알고리즘(Bellman-Ford Algorithm)

    2023.03.30
  • [Algorithm] 페르마의 소정리

    [Algorithm] 페르마의 소정리

    2023.03.18
  • [Algorithm] 플로이드-워셜(Floyd-Warshall)

    [Algorithm] 플로이드-워셜(Floyd-Warshall)

    2023.03.12
다른 글 더 둘러보기

정보

Arc 블로그의 첫 페이지로 이동

Arc

  • Arc의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그
  • 방명록

카테고리

  • 분류 전체보기 (106)
    • Language (28)
      • C++ (0)
      • C# (0)
      • Java (28)
    • Algorithm (47)
      • Algorithm (15)
      • Data Structure (6)
      • PS (26)
    • Computer Science (22)
      • Design Pattern (1)
      • Network (14)
      • OS (7)
    • Game (0)
      • Unity (0)
    • Backend (3)
      • Spring (1)
      • JPA (2)
    • DB (0)
      • SQL (0)
    • DevOps (2)
      • AWS (0)
      • Docker (2)
      • Jenkins (0)
      • Nginx (0)
    • Software Engineering (4)
      • OOP (4)
    • AI (0)
      • Machine Learning (0)
    • Others (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • network
  • 자바
  • 알고리즘
  • algorithm
  • 네트워크
  • 그래프
  • java
  • graph

나의 외부 링크

정보

SeoArc의 Arc

Arc

SeoArc

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © SeoArc. Designed by Fraccino.

티스토리툴바