문제
외판원 순회 문제는 영어로 Traveling Salesman problem (TSP) 라고 불리는 문제로 computer science 분야에서 가장 중요하게 취급되는 문제 중 하나이다. 여러 가지 변종 문제가 있으나, 여기서는 가장 일반적인 형태의 문제를 살펴보자.
1번부터 N번까지 번호가 매겨져 있는 도시들이 있고, 도시들 사이에는 길이 있다. (길이 없을 수도 있다) 이제 한 외판원이 어느 한 도시에서 출발해 N개의 도시를 모두 거쳐 다시 원래의 도시로 돌아오는 순회 여행 경로를 계획하려고 한다. 단, 한 번 갔던 도시로는 다시 갈 수 없다. (맨 마지막에 여행을 출발했던 도시로 돌아오는 것은 예외) 이런 여행 경로는 여러 가지가 있을 수 있는데, 가장 적은 비용을 들이는 여행 계획을 세우고자 한다.
각 도시간에 이동하는데 드는 비용은 행렬 W[i][j]형태로 주어진다. W[i][j]는 도시 i에서 도시 j로 가기 위한 비용을 나타낸다. 비용은 대칭적이지 않다. 즉, W[i][j] 는 W[j][i]와 다를 수 있다. 모든 도시간의 비용은 양의 정수이다. W[i][i]는 항상 0이다. 경우에 따라서 도시 i에서 도시 j로 갈 수 없는 경우도 있으며 이럴 경우 W[i][j]=0이라고 하자.
N과 비용 행렬이 주어졌을 때, 가장 적은 비용을 들이는 외판원의 순회 여행 경로를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 도시의 수 N이 주어진다. (2 ≤ N ≤ 10) 다음 N개의 줄에는 비용 행렬이 주어진다. 각 행렬의 성분은 1,000,000 이하의 양의 정수이며, 갈 수 없는 경우는 0이 주어진다. W[i][j]는 도시 i에서 j로 가기 위한 비용을 나타낸다.
항상 순회할 수 있는 경우만 입력으로 주어진다.
출력
TSP는 NP-Complete.
안녕하세요 :) 주말 잘 보내시고 계신가요 ㅎㅎ?비도 오고 그래서 뭔가 코딩하기 싫은...날이라서 계속 쓰자고 쓰자고 마음먹었던 NP-Hardness의 3탄!!!!바로 TSP(Traveling Salesman Problem)는 NP-Complete라는
zeddios.tistory.com
아마 외판원 문제라면 이 tistory를 확인하면 좋을 것 같다. 어떻게 해결할까에 대해서 계속 고민했다.
[Swift][DFS] 백준 10971번 (외판원 순회 2)
요구능력 : DFS에 대한 이해 코드설명 : 문제의 입력에는 4 0 10 15 20 5 0 9 10 6 13 0 12 8 8 9 0 가 적혀있다. 나처럼 이해못하는 사람을 위해서 해석해보자면, 도시가 4개 있는데, 1번도시는 1번에서 1번가
sapjilkingios.tistory.com
구현은 이 tistory를 확인했다. 너무 어려웠다...
func sol10971() {
let N = Int(readLine()!)!
var nodeArr:[[Int]] = []
for i in 0..<N {
let tempInput = readLine()!.split(separator: " ").map{Int($0)!}
nodeArr.append(tempInput)
}
var minSum = Int.max //합 초기화
var visited = Array(repeating: false, count: N) //visited라는 bool형 Array를 통해 접근한다.
func dfs(_ currentInd: Int, _ depth:Int, _ currentSum: Int) { //세가지 인자를 받는다.현재 Ind, depth, 현재 합계
//세가지 인자를 통해 값을 계산한다.
if depth == N && currentInd == 0{
minSum = min(minSum, currentSum)
return
}
for i in 0 ..< N {
if nodeArr[currentInd][i] > 0 && !visited[i] {
// 만약 nodearr[이전][현재]가 0보다 작지 않고 -> 작다면 갈 수 없다(ex. nodeArr[0][0] = 0)
// 접근했던 자료형이 아니라면
visited[i] = true // 현재 값을 false로 바꾼다.
let tempSum = currentSum + nodeArr[currentInd][i] //현재 임시 합계에 값을 더한다.
if tempSum < minSum { //만약 임시 합계가 현재 minSum보다 크다면? 비교할 가치가 없다.
dfs(i, depth + 1, tempSum)
}
visited[i] = false
}
}
}
dfs(0, 0, 0)
print(minSum)
}
'알고리즘' 카테고리의 다른 글
[Swift 알고리즘] 백준 1339 (단어 수학) (0) | 2023.04.11 |
---|---|
[Swift 알고리즘] 백준 2529 (부등호) (0) | 2023.04.09 |
[Swift 알고리즘]백준 10819(차이를 최대로), 백준 16193(차이를 최대로 2) (그림있음) (1) | 2023.04.06 |
[Swift 알고리즘]백준 10819(차이를 최대로) 브루스트포스 (0) | 2023.04.05 |
[Swift 알고리즘] 백준 10972(다음순열) (0) | 2023.04.04 |