본문 바로가기

Computer Science36

[알고리즘] 플로이드-워셜 (Floyd-Washall) 플로이드 워셜이란? 모든 노드 사이의 최단 거리를 구하는 알고리즘이며, 음의 가중치에도 사용할 수 있습니다. 시간 복잡도는 O(V^3)으로 그래프의 크기가 작을 때만 사용할 수 있습니다. 어떻게 동작하나? 어떤 임의의 두 노드를 연결하기 위해, 중간 노드를 하나씩 포함시킨 거리와 비교하여 업데이트를 하는 방식입니다. 임의 두 노드(s, e) 사이의 최단거리를 d[s][e]라고 하고, 중간 노드를 m이라고 한다면, 아래와 같은 식을 모든 노드 조합에 반복하는 것입니다. d[s][e] = min(d[s][e], d[s][m] + d[m][e]) 수도 코드로 표현하면 다음과 같습니다. d = 인접행렬로 그래프 표현 for (중간 노드 m in Nodes) for (출발 노드 s in Nodes) for (도착.. 2023. 1. 20.
[알고리즘] Disjoint Set. aka, 서로소 집합. aka, Union - Find Disjoint Set이란? Disjoint Set을 번역하면 서로소 집합입니다. 이는 공통된 원소를 가지고 있지 않는 집합들을 표현하는 자료 구조 입니다. 즉, 교집합이 공집합이고, 상호배타적입니다. https://ko.wikipedia.org/wiki/%EC%84%9C%EB%A1%9C%EC%86%8C_%EC%A7%91%ED%95%A9 서로소 집합 - 위키백과, 우리 모두의 백과사전 위키백과, 우리 모두의 백과사전. 집합론에서 서로소 집합(-素集合, 영어: disjoint sets)는 공통 원소가 없는 두 집합이다.[1] 예를 들어서 {1, 2, 3}과 {4, 5, 6}은 서로소이며 {1, 2, 3}과 {3, 4, 5}는 아니다. ko.wikipedia.org 어떻게 표현하나? 기본적인 원리는, 각 집.. 2023. 1. 17.
[알고리즘] Kruskal 알고리즘 (feat. Union-Find) Kruskal 알고리즘이란? MST(최소신장트리)를 찾는 알고리즘 중 하나입니다. MST란 모든 노드를 사이클 없이 연결하는 신장 트리 중, 비용을 최소로 하는 트리입니다. MST를 찾는 알고리즘은 Kruskal과 Prim 알고리즘이 있으며, dense graphs인 경우에는 Prim이, 그렇지 않은 경우에는 Kruskal이 빠르다고 하니, 상황에 맞게 선택하면 될 것 같습니다. 참고 : https://www.geeksforgeeks.org/difference-between-prims-and-kruskals-algorithm-for-mst/ Difference between Prim's and Kruskal's algorithm for MST - GeeksforGeeks A Computer Science.. 2023. 1. 16.
[알고리즘] 위상 정렬 위상 정렬이란? 그래프를 정렬하는 것입니다. 다시 말해, 방향이 있는 그래프에서 노드 전체를 탐색하는 순서를 1차원으로 나열한 것입니다. 위상 정렬을 수행하기 위해서 두 가지 제약 조건이 존재합니다. 첫째는 언급한 것처럼 방향을 가진 그래프여야하고, 둘째는 그래프에 사이클이 없어야합니다. 당연히 사이클이 있다면 그래프의 시작 지점을 특정할 수가 없습니다. 위상 정렬 방법 진입 차수를 기준으로 위상정렬을 수행할 수 있습니다. 진입 차수[In-Degree]란, 한 노드로 들어오는 간선의 수입니다. 아래의 그래프를 보시죠. [A] → [B] → [D] ↘︎ [C] ↗︎ 위에 A부터 순서대로 진입 차수는 [0, 1, 1, 2] 입니다. 여기서 진입 차수 0의 의미는 가장 먼저 시작하는 노드가 됩니다. 또한, 아.. 2023. 1. 15.
[알고리즘] 누적합 (Prefix Sum) 누적합은 구간의 합을 빠르게 구하는 방법입니다. 1차원 배열에서의 누적합 아래와 같은 1차원 배열이 있습니다. A = [4, -2, 1, 5, -3] 위의 배열에서 인덱스 1번부터 3번까지의 합을 구하고자 합니다. 그럼 -2 + 1 + 5 = 4를 계산해야하니 시간복잡도는 O(N)입니다. 그런데 배열이 크고, 구간합을 자주 계산하게 된다면 시간이 오래 걸리기 때문에, 이럴 때 사용하는 것이 누적합니다. 누적합은 말그대로 누적해서 더하는 것입니다. 아래처럼요. S[n+1] = sum(0, n) 인덱스 0번부터 n번의 합 ( 계산의 편의를 위해 s[0]번은 비워둠 ) S = [0, 4, 2, 3, 8, 5] 일단 누적합을 계산해두고나면, 구간합을 아주 빠르게 구할 수 있습니다. 위의 예시처럼 인덱스 1번부터.. 2023. 1. 13.
[알고리즘] 벨만 포드 알고리즘 (Bellman-Ford) Bellman-Ford Algorithm 이 알고리즘은 모든 간선을 전부 확인하여, 음수 가중치도 문제도 해결할 수 있습니다. 1. 엣지 리스트를 활용한다. 위에 언급한 것처럼, '모든 간선(엣지)'를 전부 확인함으로 엣지 리스트를 사용하는 편이 직관적이고 효율적입니다. 엣지 리스트란, 단순하게 모든 엣지 정보(시작 노드, 도착 노드, 비용)을 담은 리스트입니다. 2. 'update'를 노드의 개수 - 1번 만큼 반복한다. 우선, 다익스트라에서 사용한 것과 유사하게, 최소 비용 배열을 선언한 후, 모두 무한의 값으로 초기화합니다. (최소비용배열[N] = 시작 노드에서 출발하여 N번 노드로 가는 최소비용) 이 배열의 시작 노드 값을 0으로 설정합니다. 이제 Update는 아래와 같습니다. 엣지 리스트를 순.. 2023. 1. 13.
[알고리즘] BFS와 다익스트라 알고리즘 들어가며 오늘은 그래프에서 최단 경로를 찾는 방법에 대해 정리해보려합니다. 정리 상황에 맞는 알고리즘을 잘 정리해둔 것을 보아서 가져와봤습니다. 단일 node - 단일 node 모든 node쌍 Edge에 weight 없음 Breadth First Search (BFS) Floyd-Warshall Algorithm Edge에 weight 있음 음수 weight 있음 Bellman-Ford Algorithm 음수 weight 없음 Dijkstra Algorithm 출처: https://shnoh.tistory.com/15 BFS (너비 우선 탐색) 가장 단순한 형태입니다. weight가 없으니 depth가 곧 거리가 될 것이기 떄문에, 한 depth를 모두 살핀 후 그 다음 depth를 탐색하는 BFS를 통.. 2023. 1. 13.
[알고리즘] 행렬의 제곱 (백준 2099, The game of death)(feat. 인접행렬, 인접리스트) 들어가며 오늘 백준 문제를 풀다 시간 초과로 인해 결국 서치를 해봤는데, 행렬의 제곱을 이용해서 풀러야한다는 것을 알고 충격을 받았습니다... 역시 알고리즘,, 아직 배울 것이 너무 많이 남았습니다. 아무튼 새로운 영역을 배우게 되어 저 같은 사람들에게 조금이나마 도움이 되고자 글을 적습니다. 우선은 행렬이란?!(인접 리스트와 비교하여) 알고리즘에서 그래프를 표현하는 방법에는 두 가지가 있습니다. 1. 인접 행렬 2. 인접 리스트 인접 행렬 그 중 인접 행렬에 대해 우선 알아보겠습니다. 아래는 그래프를 행렬로 표현한 것입니다. 행렬에서 (A, B) 가 1이면, A에서 B로 가는 간선이 있다. 0이면, 없다는 의미가 됩니다. 또한 행렬의 모든 수를 더하면, 해당 그래프의 모든 간선의 수가 됩니다. 위의 그.. 2022. 12. 20.
[알고리즘] LIS 최장 증가 부분 수열, SegmentTree 최장 증가 부분 수열이란? A라는 수열ㄹ에서 연속되는 것과 상관없이 Ai < Aj (단, i < j)를 만족하는 부분 수열입니다. [10, 20, 10, 30, 20, 50] 위와 같이 수열이 주어졌을 때, [10, 20] [10, 20, 30] [10, 20, 30, 50] ... 모두 증가 부분 수열이며, 그 중 가장 길이가 긴 부분 수열이 최장 증가 부분 수열입니다. 어떻게 구하나? 동적계획법을 이용하여 구할 수 있습니다. 수열 A가 주어졌을 때, D(i)를 i번째 수를 부분 수열의 마지막으로하는 부분 수열 중 가장 길이가 긴 수열의 길이라고 한다면, D(i)는 Ai보다 앞에 있고 Ai보다 작은 Aj의 j에 대하여 D(j)가 가장 큰 값 + 1이될 것입니다. 즉 index 0부터 차례로 순회하며 D.. 2022. 10. 10.