티스토리 뷰
Explain
- Floyd-Warshall algorithm 또는 Floyd's algorithm 이라고 불리우며 negative cycles을 가지지 않은 weighted graph에서 임의의 두 vertex 사이의 최단 거리를 구하는 알고리즘이며 \(\Theta(n^3) \) 의 시간복잡도를 나타내며 optimal algorithm의 한 종류이다.
Notation
- \(N :\) vertex 의 개수
- \(W :\) 인접 vertex 간의 weight \( |N^2| \) 이며 인접하지 않은 vertex 간의 거리는 \(\infty\)
- \( D_{(k)}[i,j] = \) from i to j 의 경로중 k 이하의 vertex만을 통과하여 얻을 수 있는 최단거리
- \( D_{(0)}[i,j] = W[i,j] \) 0이하의 vertex만을 통과하여 i,j를 지나는 경로는 해당 edge의 weight이다.
Algorithm
- \( D_{(0)}[i,j] = W[i,j] \) 를 활용하여 \( D_{(0)}[1...N,1...N] \)을 구할 수 있으며
- 이후, \( D_{(1)}[i,j] \) 의 경우를 생각해보면
- \(i \rightarrow j\) , \(i \rightarrow 1 \rightarrow j\)
- 위 2가지 경우로 나눌수 있으며 그러므로
- \( D_{(1)}[i,j] = \min(D_{(0)}[i,j], D_{(0)}[i,0] + D_{(0)}[0,j])\) 이다.
$$\text{thus,} D_{(k)}[i,j] = \min(D_{(k-1)}[i,j],D_{(k-1)}[i,k] + D_{k-1}[k,j])$$
- 즉, \(D_{(k-1)}\) 을 구하면 \(D_{k}\) 를 구할 수 있다.
Code_only shortest distance
//Floyd's algorithm
#include <stdio.h>
#define MAX 5
#define INF 99999
int min(int x,int y);
void floyds(int n,int W[][MAX]);
void display(int n, int D[][MAX]);
int main(void)
{
// 두 vertex간의 거리
int W [MAX][MAX] = {
{0,1,INF,1,5},
{9,0,3,2,INF},
{INF,INF,0,4,INF},
{INF,INF,2,0,3},
{3,INF,INF,INF,0}
};
int D[MAX][MAX];
floyds(5,W,D);
}
void display(int n,int D[][MAX])
{
int i,j;
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
if(D[i][j] == INF)
printf("%5s","INF");
else
printf("%5d", D[i][j]);
}
puts("");
}
}
void floyds(int n, int W[][MAX], int D[][MAX])
{
int k,i,j,l;
D=W;
for(k=0;k<n;++k)
{
for(l=0;l<n;++l)
{
D[k][l] = W[k][l];
D[l][k] = W[l][k];
}
for(i=0;i<n;++i)
{
if(i==k){
continue;
}
for(j=0;j<n;++j)
{
if(j==k) continue;
if(i==j) continue;
D[i][j] = min(D[i][j], D[i][k] + D[k][j]);
}
}
}
display(5,D);
}
int min(int x,int y)
{
if(x>y) return y;
return x;
}
Code_distance with shortest path.
\(P[i,j] = D[i,j]\)의 intermediate point 라고 했을때,
$$\text{if }D_{(k-1)}[i,j] > D_{(k-1)}[i,k] + D_{(k-1)[k,j]} $$
위 조건문이 성립하는경우 최단 경로는 \(i\rightarrow k \rightarrow j\) 이므로 \(P[i,j] = k\) 이다.
//Floyd's algorithm
#include <stdio.h>
#define MAX 5
#define INF 99999
int min(int x,int y);
void floyds(int n,int W[][MAX], int D[][MAX]);
void display(int n, int D[][MAX]);
void print_path(int start, int end, int P[][MAX]);
int main(void)
{
// 두 vertex간의 거리
int W [MAX][MAX] = {
{0,1,INF,1,5},
{9,0,3,2,INF},
{INF,INF,0,4,INF},
{INF,INF,2,0,3},
{3,INF,INF,INF,0}
};
int D[MAX][MAX];
floyds(5,W,D);
}
void display(int n,int D[][MAX])
{
int i,j;
for(i=0;i<n;++i)
{
for(j=0;j<n;++j)
{
if(D[i][j] == INF)
printf("%5s","INF");
else
printf("%5d", D[i][j]);
}
puts("");
}
}
void floyds(int n, int W[][MAX], int D[][MAX])
{
int k,i,j,l;
int P[MAX][MAX] = {0};
D=W;
for(k=0;k<n;++k)
{
for(l=0;l<n;++l)
{
D[k][l] = W[k][l];
D[l][k] = W[l][k];
}
for(i=0;i<n;++i)
{
if(i==k){
continue;
}
for(j=0;j<n;++j)
{
if(j==k) continue;
if(i==j) continue;
if(D[i][j] > D[i][k] + D[k][j])
{
P[i][j] = k;
D[i][j] = D[i][k] + D[k][j];
}
}
}
}
printf("shortest path from 1 to 0\n");
printf("%d->",1);
print_path(1,0,P);
printf("%d\n",0);
}
void print_path(int start, int end, int P[][MAX])
{
if(P[start][end] != 0)
{
print_path(start, P[start][end], P);
printf("%d->",P[start][end]);
print_path(P[start][end], end, P);
}
}
int min(int x,int y)
{
if(x>y) return y;
return x;
}
Reference
'Algorithm' 카테고리의 다른 글
2448_별찍기 - 11 (0) | 2016.10.13 |
---|---|
Matrix chain multiplication (0) | 2016.10.12 |
4673_셀프 넘버 (0) | 2016.10.05 |
1065_한수 (0) | 2016.10.05 |
Matrix multiplication 행렬의 곱셈 (0) | 2016.09.19 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- mysql
- Kotlin
- 비트연산자
- 알고리즘
- DNS
- Bit
- 행렬
- Math
- syntax highlighting
- python
- 안드로이드
- 삼항연산자
- 비트
- 도메인
- 비트마스크
- highlightjs
- Highlighter
- C
- Android
- robocopy
- 수식
- algorithm
- mathjax
- Matrix
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
글 보관함