본문 바로가기

알고리즘

알고리즘16-1

728x90

모든 쌍의 shortest (길이만 구하기. 실제 path까지 구하는 것은 조금 어려우니 skip)

그래프에서 source가 정해지면 다른 노드로 가는 shortest path구하기

 

노드가 n개 있다면 출력할 값이 n^2개

1번에서 2번으로 가는 shortest path

2번에서 1번으로 가는 shortest path는 undirect냐 direct냐 에 따라 다르지만

undirect graph로 설명하겠다 => 같다

 

 

입력과 바로 매치가 안되서 어렵다.


* Dijkstra로 다 돌리면 시간이 O((m+n) log n)

보통 m>n이기 때문에 O(m logn)라고 표현 가능

(m: edge갯수 , n:node갯수)

 

모든 쌍의 Shortest Path구하기는

source node를 정하기 위해 이 과정을 n번 돌려야 한다.

=> O(n(m+n) log n)

 

 

이것보다 느리지 않지만 살짝 애매하다 (?)

 

 

m은 최대 n^2이다. (오늘 배울 것. 근데 annotation보단 실제가 훨씬 빠르다.)

=> O((n^3))

 

m이 작으면

=> O(n logn)

 

 

어떤 작전으로 풀 것인가?

 

노드는 1부터 N번까지 번호가 붙어있음.

k는 1씩 증가하면서 변할때, 노드 i에서 노드j로 가는 shortest path를 단계적으로 진행한다.

단, 1번부터 k번까지만 쓰는 shortest path를 구한다. (다 쓰는 것이 아니라 이 안에서 써야함)

 

ex)

i>10

j>10일때

 

k=0이라면 {공집합}이고 i와 j를 연결하는 것은 direct edge밖에 없다.

direct edge가 없다면 답은 무한대가 된다.

 

 

k=1이라면 1번 노드가 있다. {1}

(1번을 거쳐갈 수 있다.)

엣지가 없다면 못가는 거고 (무한대)

있다면 거쳐갈 수 있다.

하지만 안 거쳐가는 경우가 10으로 더 빠르므로 10

 

 

k=2라면 {1,2}

그냥 가는 방법 : 10

1만 거쳐 가는 방법: 12

2만 거쳐 가는 방법: 9

1,2를 거쳐 가는 방법: 8 (5+2+1)

2,1을 거쳐 가는 방법: 17

 

1번만 있을 때 1을 안썼다고 해서 2가 추가되었을 떄 1을 안쓰는 것이 답이 아니다.

 

 

k=0 답:10

k=1 답:10

k-2 답:8

 


초기값은 D[0][i][j]은 edge weight이다. 이차원 배열 w[i][j] 

 

0<=k<n, 1<i=n, 1<=j<n

계산하는 값의 갯수가 n^3개

하나의 값을 상수시간에 계산하면 된다.

 

D[k][i][j]

= {1,2,...,k} 중에서 거쳐서 i->j 인 shortest path

 

계속 k를 증가시키며 D[k-1][i][j]을 통해 D[k][i][j]을 계산하겠다.

(1<i=n, 1<=j<n

 

끝까지 가면 k=n일때 {1,2,3,...n} => 모든 노드를 가지고 만들어낸 shortest path

최종 답 = D[n][i][j] 

(재사용이 되서 성능이 좋다.)

 


D[k-1][i][j]을 이미 가지고 있다.

노드i에서 노드j로 가는데 {1,2,...k}만 써서 갈 수 있는 제일 짧은 길을 찾아야 한다.

모르지만, k를 쓸 수도 있고 안쓸 수도 있다. 

 

i부터 j까지 가는 shortest path에 같은 노드가 2번 쓰일 수 있나? ㄴㄴ

따라서 노드 k를 반드시 쓰는 shortest path  => D[k-1][i][k]+D[k-1][k][j]

 

노드 k를 안쓰는 shortest path => D[k-1][i][j]와 같다.

둘 중 더 짧은 것이 정답이겠지!  MIN( D[k-1][i][k]+D[k-1][k][j] ,  D[k-1][i][j] )

 

 

 

 

 

 

 

 

 

 

 

'알고리즘' 카테고리의 다른 글

알고리즘17 근사문자열매칭과 거리함수  (0) 2020.10.29
알고리즘 16-2  (0) 2020.10.25
알고리즘15-2  (0) 2020.10.25
알고리즘15  (0) 2020.10.25
14-2  (0) 2020.10.17