알고리즘 20

[알고리즘] 부분집합 합 문제, sum of subsets problem

sum of subsets problem이란 n개의 양의 정수(w1,w2,...,wn)와, 임의의 양의 정수 W가 있을 때, 다 합쳐서 W가 되는 모든 부분집합을 구하는 문제이다. 이 문제를 백트래킹을 사용하여 해결할 수 있다. 먼저 backtracking 문제를 풀기위해서는 상태공간트리의 구조와, 유망함수를 구축해야한다. sum of subsets 문제의 경우 상태공간트리의 구조와 유망함수는 다음과 같다. ① 상태공간트리의 구조 오름차순으로 level을 결정 ② 유망함수(promising function) weight + wi+1이 W보다 큰가? ≫ non-promising weight + total이 W보다 작은가? ≫ non-promising 양의 정수들을 오름차순으로 정렬하고, 작은 것 부터 즉 ..

[알고리즘] Monte Carlo Algorithm, 몬테카를로 알고리즘

Monte Carlo 알고리즘은 backtracking 알고리즘의 성능을 추정할 때 사용하는 알고리즘이다. Monte Carlo 알고리즘은 어떤 입력이 주어졌을 때 그에 따라 생성되는 상태공간트리의 전형적인 경로를 무작위로 생성하고 그 경로상에 있는 노드의 수를 센다. 이 과정을 여러 번 반복하여 나오는 결과의 평균치가 곧 추정치가 된다. 이처럼 Monte Carlo 알고리즘은 무작위 표본의 추정치를 사용하여 무작위 변수의 기대치를 측정하는 확률적 알고리즘이다. 이 알고리즘을 사용하기 위해 만족해야할 조건 2가지는 아래와 같다. ① 상태공간트리에서 같은 수준(level)에 있는 모든 노드에서는 같은 유망함수를 사용해야 한다. ② 상태공간트리에서 같은 수준에 있는 모든 노드들은 같은 수의 자식노드들을 가지..

[알고리즘] n-Queens Problem | 설계 및 분석

n-Queens 문제란, nxn의 체스판에 n개의 퀸을 서로 충돌하지 않게 놓는 방법을 구하는 문제이다. 즉 서로 상대방을 위협하지 않도록 같은 행이나 같은 열, 또는 같은 대각선 상에 위치하지 않아야한다. 모든 경우를 따져가며 방법을 찾기에는 n이 커질수록 매우 다양한 경우를 따져야하므로 우리는 n-Queens문제에 backtracking 알고리즘을 적용하여 상태공간트리를 만들고, 유망한 노드들의 자식만 검사함으로써 검사해야 할 경우를 줄일 수 있다. n-Queens문제에 backtracking 알고리즘을 어떻게 적용하여 문제를 해결할 수 있는지 알아보자. 이전 글에서도 설명했다시피, backtracking 문제를 풀기위해 결정되어야 할 사항은 다음과 같다. ① 상태공간트리의 구조를 결정 ② 유망한지 ..

[알고리즘] 되추적 알고리즘, Backtracking

backtracking은 깊이우선탐색(DFS) 방식으로 상태공간트리를 탐색하는 알고리즘으로, 최적화 문제를 해결하는데에 사용될 수 있다. backtracking의 진행절차는 다음과 같다. ① 상태공간트리의 깊이우선검색(DFS)을 실시 ② 각 노드가 유망(promising)한지 점검 ③ 유망하지 않은 노드들은 더 이상 검색하지 않고 그 노드의 부모노드로 돌아가서 검색을 계속(pruning), 유망한 노드들은 그 노드의 자식노드를 검색 여기서 promising, 즉 유망하다는 것은 더 내려다볼 가치가 있다는 것이고 반대로 유망하지 않다(non-promising)는 것은 전혀 해답이 나올 가능성이 없다는 것을 의미한다. 유망하지 않으면 그 자식노드에 대한 탐색을 중단하고 부모노드로 돌아가는데, 이를 '가지친다..

[알고리즘] 다익스트라 알고리즘, Dijkstra's Algorithm | 설계 및 분석, 구현코드

다익스트라 알고리즘은 가중치가 있는 방향성 그래프에서 한 특정 정점에서 다른 모든 정점으로 가는 최단경로를 구하는 문제이다. 앞서 살펴본 프림 알고리즘, 크루스칼 알고리즘과 마찬가지로 최단 경로를 구하는 문제이며 그래프를 사용한다는 점에서 공통점이 있지만 다익스트라 알고리즘은 Minimum Spanning Tree를 구하는 문제가 아니라는 점에서 차이가 있다. 아래의 수도코드를 보면 프림 알고리즘의 수도코드와 유사하다는 것을 알 수 있지만, 이미 방문한 집합 V-Y에서부터 정점 v까지의 최단거리를 선택하는 프림 알고리즘과 달리 다익스트라 알고리즘은 출발점부터 정점 v까지의 최단거리를 구한다. 수도코드(high level) F:=∅ Y:={v1}; while(the instance is not solved..

[알고리즘] 크루스칼 알고리즘, Kruskal's Algorithm | 설계 및 구현코드

크루스칼 알고리즘은 프림 알고리즘과 달리 한 정점이 locally optimal한지 결정할 때 단순히 edge의 가중치를 기준으로 결정한다. 즉, edge의 가중치가 작으면 작을수록 locally optimal한 것이다. 가중치가 작은 것 부터, 즉 유리한 것 부터 먼저 담으려는 크루스칼 알고리즘의 의도가 참 말그대로 'Greedy' 해보인다. 하지만 크루스칼 알고리즘이 대책없이 edge들을 마구마구 담아대는 것은 아니다. 순환 경로가 발생하지 않도록 정점들의 관계를 검사하는 작업을 치른다. 이 과정에 대해 더 자세히 알아보도록 하자. 수도코드(high level) F := ∅; //edge의 집합 초기화 create disjoint subsets of V, one for each vertex and c..

[알고리즘] 프림 알고리즘, Prim's Algorithm | 설계 및 분석

프림 알고리즘의 locally optimal의 기준은 이미 방문한 정점들의 집합 Y에서부터 방문한 적이 없는 한 정점까지의 거리이다. 즉, 방문한 적이 없는 정점들 중 출발점과의 거리가 가장 가까운 정점부터 선택한다는 것이다. 이 과정을 간단한 수도코드와 그림으로 나타내면 다음과 같다. 수도코드(high level) F := ∅; //edge의 집합 Y := {v1}; //vertex의 집합, 출발점을 포함한 상태로 시작 while(the instance is not solved) { select a vertes in V-Y that is nearest to Y; //selection procedure, feasibility check add the vertex to Y; add the edge to F..

[알고리즘] 최소비용 신장트리, Minimum Spanning Tree

greedy approach를 신장트리로 시각화할 수 있다. 신장트리는 정점이 서로 연결되어있고 방향이 없는 그래프에서 순환 경로가 없도록 엣지를 제거하되 모든 정점이 그래프에 포함되도록 연결한 부분 그래프이다. 여기서 비용이 최소가 되도록 연결한 그래프(신장트리)를 최소비용 신장트리라고 한다. 글로만 읽으면 무슨 말인지 이해가 잘 안될테니 그림으로 이해해보자. 아래 그림은 신장트리의 한 예를 보여준다. 위 그림의 신장트리가 과연 최소신장트리일까? 오른쪽의 신장트리가 왼쪽의 그래프에서 도출될 수 있는 그래프들 중 비용이 가장 적은 그래프일까? 그렇지 않다. 비용이 더 작은 엣지들을 사용해서도 충분히 모든 정점들을 이으면서 순환 경로가 없도록 그래프를 만들 수 있다는 것을 알 수 있다. 하지만 이는 위의 ..

[알고리즘] 탐욕 알고리즘, The Greedy Approach

미래의 결과를 예측할 수 없는 상황에서 지금 내가 할 수 있는 최선의 결정은 무엇일까? 매 선택마다 그 순간에 가장 좋다고 생각되는 것을 선택하는 것이다. 즉, 그 순간에 가장 좋다고 생각되는 것을 선택함으로써 최종적인 해답에 도달한다. 매 순간 가장 좋다고 생각되는 것을 선택하면 그것이 궁극적으로도 최적이 될 수도 있기 때문이다. 이러한 원리의 접근방식이 바로 Greedy Approach이다. 하지만 이는 미래를 고려하지 않고 단지 그 순간에서의 optimal한 것을 선택한 것이므로, 그 해답이 궁극적으로 optimal라는 보장이 없다. 따라서 최적의 해답을 주는 알고리즘인지 검증하는 과정이 반드시 필요하다. 따라서 Greedy Approach 알고리즘의 구성은 다음과 같다. ① 선택 절차, selec..

[알고리즘] 외판원 문제, TSP(The Traveling Salesperson Problem) | 설계 및 분석

외판원 문제란? home city에서 출발해 모든 city를 한번씩 거치고 다시 home city로 돌아오는 최단 경로를 구하는 문제이다. 만약 무식하게 모든 경우의 수를 다 알아본 후 가장 짧은 경로를 찾는다면 그 성능은 어떻게 될까? (n - 1)! 즉 O(n!)이라는 결과가 나온다. 이렇게 비효율적인 방법은 쓸모가 없으므로 우리는 동적계획법을 사용하여 TSP를 풀어보려고 한다. ① W : 그래프의 인접행렬 W[i][j] = 이음선의 가중치 (vi에서 vj로의 이음선이 있는 경우) = ∞ (vi에서 vj로의 이음선이 없는 경우) = 0 ( i = j인 경우 ) ② V : 모든 정점들이 담긴 집합 ③ A : V의 부분집합 ④ D[vi][A] : vi에서 A의 집합들을 한번씩 모두 지나면서 v1로 가는 ..