[세호/week6] 그래프의 개념과 정의, 탐색 방법
그래프 그래프는 유한하고, 하나 이상의 원소를 갖는 Vertex 집합과 Vertex의 부분집합의 순서있는 쌍으로 이루어진 Edge의 집합으로 이루어진다. Edge는 Vertex의 쌍 (v1, v2)와 같이 나타내고, 방향그래프에서 순서는 유의미하다 헷갈리는 그래프 관련 ...
분할 정복법(Divide and Conquer)은 여러 알고리즘의 기본이 되는 해결 방법으로, 기본적으로는 엄청나게 크고 방대한 문제를 조금씩 조금씩 나눠가면서 용이하게 풀 수 있는 문제 단위로 나눈 다음 그것들을 다시 합쳐서 해결하자는 개념에서 출발하였다. 대표적으로는 퀵소트나 합병 정렬이 있다.
분할 정복법은 재귀적으로 자신을 호출하면서 그 연산의 단위를 조금씩 줄어가는 방식이다. 예는 아래와 같다.
function F(x):
if F(x)가 간단 then:
return F(x)를 계산한 값
else:
x 를 x1, x2로 분할
F(x1)과 F(x2)를 호출
return F(x1), F(x2)로 F(x)를 구한 값
문제를 나눔으로써 어려운 문제를 해결할 수 있다는 엄청난 장점이 있다.
함수를 재귀적으로 호출한다는 점에서 함수 호출로 인한 오버헤드가 발생하며, 스택에 다양한 데이터를 보관하고 있어야 하므로 스택 오버플로우가 발생하거나 과도한 메모리 사용을 되는 단점이 있다. 가장 중요한 것은 이 알고리즘의 핵심인 “F(x)가 간단”이 어떤 것이냐에 따라 알고리즘의 퍼포먼스가 생각보다 꽤 차이나게 된다는 것이다. 이 “F(x)가 간단하다”라는 것을 정의하는 것의 난해함 역시 단점 중에서 중요하게다루어지고 있다.
//필수조건 : n은 자연수
int fatsum(int n){
if (n==1) return 1;
if (n % 2 == 1) reutrn fatSum(n-1) + n;
return 2 * fatSum(n/2) + (n/2)*(n/2);
}
주어진 수열을 크기 순서대로 정렬 알고리즘에서 병합정렬과 퀵정렬은 모두 분할 정복 패러다임을 기반으로 해서 만들어진 것이다.
주어진 수열을 가운데에서 쪼개 비슷한 크기의 수열 두개로 만든 뒤 이들을 재귀 호출을 이용해 각각 정렬한 후 정렬된 배열을 하나로 합치는 방식.
int sorted[100];
void mergesort(int list[], int left, int right){
int mid;
if (left < right){
mid = (left + right) / 2; //중간 위치를 계산하여 리스트를 균등 분할 - Divide(분할)
mergesort(list, left, mid); //앞쪽 부분 리스트 정렬 - Conquer (정복)
mergesort(list, mid+1, right); //뒤쪽 부분 리스트 정렬 - Conquer (정복)
merge(list, left, mid, right); //정렬된 2개의 부분 배열을 합병하는 과정 - Combine (결합)
}
}
void merge(int list[], int left, int mid, int right){
int i, j, k, l;
i = left; j = mid+1; k = left;
//분할 정렬된 list 합병
while(i <= mid && j <= right){
if(list[i] <= list[j]){
sorted[k] = list[i];
k++; i++;
{
else{
sorted[k] = list[j];
k++; j++;
}
}
//남아있는 값들을 일괄 복사
if(i>mid){
for(l=j; l<=right; l++){
sorted[k] = list[l];
k++;
}
}
//남아있는 값들을 일괄 복사
else{
for(l=i; l<=mid; l++){
sorted[k] = list[l];
k++;
}
}
//배열 sorted[]의 리스트를 배열 list[]로 재복사
for(l=left; l<=right; l++){
list[l] = sorted[l];
}
}
배열을 단순하게 쪼개는 대신, 병합 과정이 필요 없도록 한쪽의 배열에 포함된 수가 다른 쪽에 배열의 수보다 항상 작도록 배열을 분할한다. 이를 위해 퀵정렬은 파티션(partition)이라고 부르는 단계를 도입하는데, 이는 배열에 있는 수 중 임의의 ‘기준 수(pivot)’를 지정한 후 기준보다 작거나 같은 숫자를 왼쪽, 더 큰 숫자를 오른쪽으로 보내는 과정.
“그래 네 말이 맞다고 치자. 근데도 문제가 생겼네. 따라서 니 말이 틀렸어” 식의 말이 귀류법이다.
수학과 논리학의 증명법 중 하나. 수학에서는 흔히 간접적 증명이라고도 부른다.
1) P(0)가 성립한다.
2) P(0),P(1),P(2),⋯,P(n)이 모두 성립하면, P(n + 1)
반복문 불변식이란 반복문의 내용이 한 번 실행될 때 마다 중간 결과가 우리가 원하는 답으로 가는 길 위에 잘 있는지 명시하는 조건. 알고리즘의 정당성을 증명할 때 사용한다.
// (*) 불변식은 여기에서 성립해야 한다.
while (어떤 조건) {
//반복문 내용의 시작
...
//반복문 내용의 끝
// (*) 불변식은 여기에서도 성립해야 한다.
}
그래프 그래프는 유한하고, 하나 이상의 원소를 갖는 Vertex 집합과 Vertex의 부분집합의 순서있는 쌍으로 이루어진 Edge의 집합으로 이루어진다. Edge는 Vertex의 쌍 (v1, v2)와 같이 나타내고, 방향그래프에서 순서는 유의미하다 헷갈리는 그래프 관련 ...
그래프(Graph)의 개념 단순히 노드(N, node)와 그 노드를 연결하는 간선(E, edge)을 하나로 모아 놓은 자료 구조
트리의 개념
트리의 구현과 순회
자료구조란? 자료구조(data structure)는 전산학에서 자료를 효율적으로 이용할 수 있도록 컴퓨터에 저장하는 방법이다. 신중히 선택한 자료구조는 보다 효율적인 알고리즘을 사용할 수 있게 한다.
동적 계획법
동적 계획법 - Dynamic Programming ; DP
분할 정복이란 문제를 둘 이상의 부분으로 나누어, 부분 문제에 대한 답을 재귀 호출을 이용해 계산하는 알고리즘 디자인. 분할 정복을 적용하기 위해서는 .. 문제를 둘 이상의 부분 문제로 나누는 자연스러운 방법이 있어야하고 부분 분제의 답을 조...
분할 정복(Divide and Conquer)이란?
분할 정복 이란? 분할정복 알고리즘은 문제를 나눌 수 없을 떄까지 나누어서 각각을 풀면서 다시 합병하여 문제의 답은 얻는 알고리즘이다.
분할정복이란
모든 경우에 있어서 항상 우월한 성능을 보이는 자료구조와 알고리즘은 없다. 그래서 자료구조와 알고리즘을 분석하고 평가할 수 있어야 한다.
Algorithm Study Week1 일자 : 2019년 10월 7일 월요일 Member : 이세호, 김범철, 이지연, 이지혜 “프로그래밍 대회에서 배우는 알고리즘 문제 해결 전략” 2, 3, 4장 키워드 : 시간복잡도와 Big-O 표기 Algospot 튜토리...
Algorithm Study Week1 일자 : 2019년 10월 7일 월요일 Member : 이세호, 김범철, 이지연, 이지혜 “프로그래밍 대회에서 배우는 알고리즘 문제 해결 전략” 2, 3, 4장 키워드 : 시간복잡도와 Big-O 표기 Algospot 튜토리...