이 영역을 누르면 첫 페이지로 이동
쿄코코 블로그의 첫 페이지로 이동

쿄코코

페이지 맨 위로 올라가기

쿄코코

얼레벌레 생활🤯

[이코테]CHAPTER 09 최단 경로 알고리즘 - 플로이드워셜 알고리즘 - Python(파이썬),Java(자바)

  • 2022.06.11 14:15
  • Study Platform📚/(알고리즘)- [이코테] 이것이 코딩테스트다 정리
    반응형

    참고자료 : https://www.youtube.com/watch?v=acqm9mM1P6o

    📎 다익스트라(Dijkstra) 알고리즘과 플로이드 워셜(Floy-Warshall) 알고리즘의 차이

    1) 다익스트라(Dijkstra) 알고리즘 

    - 자세한 설명은 : https://coooco.tistory.com/36?category=1071114

    - 한 지점에서 다른 특정 지점까지의 최단 경로를 구해야하는 경우에 사용하는 알고리즘

    - 단계마다 최단 거리를 가지는 노드를 하나씩 반복적으로 선택 -> 해당 노드를 거쳐가는 경로 확인 -> 최단 거리 테이블 갱신 

    - 그리디 알고리즘

    2) 플로이드 워셜(Floy-Warshall) 알고리즘

     - 모든 지점에서 다른 모든 지점까지의 최단 경로를 모두 구해야 하는 경우에 사용하는 알고리즘

    - 단계마다 거쳐가는 노드를 기준으로 알고리즘을 수행 -> 매번 방문하지 않은 노드 중에서 최단 거리를 갖는 노드 찾을 필요 X

    - 노드의 개수가 N개일 때, 알고리즘상으로 N번의 단계를 수행하며, 단계마다 O(N2)의 연산을 통해 '현재 노드를 거쳐가는' 모든 경로를 고려 -> 시간 복잡도 : O(N3)

    더보기

    시간 복잡도 추가 설명

    노드의 개수를 N이라고 할 때, 1부터 N까지의 노드는 모두 경유 노드가 가능하다.

    경유 노드를 제외한 (N-1)개의 노드 중 두개를 골라 시작노드,도착노드라고 가정해보자. 

    이 경우를 구하는 가지수: (N-1)P2로 계산하여 O(N2)의 시간복잡도에 경유 노드마다 반복해야하믈 시간복잡도 O(N3)이 된다.

    - 다이나믹 프로그래밍 (노드의 개수가 N이라고 할 때, N번만큼의 단계를 반복하며 점화식에 맞게 2차원 리스트를 갱신하기 때문) 

    - 시간 복잡도가 O(N3)이므로 노드,간선의 개수가 적은 경우에만 사용할 수 있으며 노드,간선의 개수가 많은 경우에는 다익스트라 알고리즘을 사용

    📌 플로이드 워셜 알고리즘 점화식

    Dab = min(Dab,Dak+Dkb)

    - a에서 b로 가는 거리(Dab)는 기존에 a에서 b로 가는 최단 거리(Dab)와 (a에서 k로 가는 거리(Dak)+ k에서 b로 가는 최단 거리(Dkb) 비교해서 더 작은 값으로 갱신

    📌 플로이드 워셜 알고리즘 동작 과정

    이렇게 연결된 노드들이 있다고 가정하면 먼저 주어진 노드들을 최단 거리 테이블에 작성한다

    1번 노드를 경로노드라고 가정하였을 때 나오는 경우의 수는 3P2 = 6가지로 앞서 계산한 최단 거리와 비교하여서 최단 거리 테이블을 갱신한다.

    2번 노드를 경로노드라고 가정하였을 때 나오는 경우의 수는 3P2 = 6가지로 앞서 계산한 최단 거리와 비교하여서 최단 거리 테이블을 갱신한다.

     

    3번 노드를 경로노드라고 가정하였을 때 나오는 경우의 수는 3P2 = 6가지로 앞서 계산한 최단 거리와 비교하여서 최단 거리 테이블을 갱신한다.

    4번 노드를 경로노드라고 가정하였을 때 나오는 경우의 수는 3P2 = 6가지로 앞서 계산한 최단 거리와 비교하여서 최단 거리 테이블을 갱신한다.

    🖥 코드 구현

    입력 출력
    4 (노드의 개수)
    7 (간선의 개수)
    1 2 4 (1번 노드에서 4번 노드로 가는 비용 : 4 )
    1 4 6
    2 1 3
    2 3 7
    3 1 5
    3 4 4
    4 3 2
    4 (노드의 개수)
    7 (간선의 개수)
    1 2 4 (1번 노드에서 4번 노드로 가는 비용 : 4 )
    1 4 6
    2 1 3
    2 3 7
    3 1 5
    3 4 4
    4 3 2

    💻Python(파이썬)

    import sys
    
    INF = int(1e9)
    
    #노드의 개수 및 간선의 개수 입력 받기
    n = int(sys.stdin.readline())
    m = int(sys.stdin.readline())
    #2차원 리스트를 만들고, 무한으로 초기화
    graph = [[INF]*(n+1) for _ in range(n+1)]
    
    #자기 자신에서,자기 자신으로 가는 노드 비용 0으로 초기화
    for i in range(1,n+1):
        graph[i][i]=0
    
    #각 간선에 대한 정보를 입력받아, 그 값으로 초기화
    for _ in range(m):
        #A에서 B로 가는 비용이 C
        a,b,c = map(int,sys.stdin.readline().split())
        graph[a][b]=c
    
    #경로 노드
    for k in range(1,n+1):
        #시작 노드
        for a in range(1,n+1):
            #도착 노드
            for b in range(1,n+1):
                graph[a][b]=min(graph[a][b],graph[a][k]+graph[k][b])
    
    for a in range(1,n+1):
        for b in range(1,n+1):
            if graph[a][b]==INF:
                print(-1,end=" ")
            else:
                print(graph[a][b],end=" ")
        print()

    💻Java(자바)

    package s15_shortest;
    
    import java.util.*;
    import java.io.*;
    
    public class e01_9_3 {
        public static final int INF = (int)1e9;
        public static int n,m;
        public static int[][] graph = new int[501][501];
        public static void main(String[] args) throws IOException{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            //노드의 개수
            int n = Integer.parseInt(br.readLine());
            //간선의 개수
            int m = Integer.parseInt(br.readLine());
            for(int i=0;i<501;i++){
                Arrays.fill(graph[i],INF);
            }
            for(int i=1;i<=n;i++){
                graph[i][i]=0;
            }
            for(int i=0;i<m;i++){
                StringTokenizer st = new StringTokenizer(br.readLine()," ");
                int a = Integer.parseInt(st.nextToken());
                int b = Integer.parseInt(st.nextToken());
                int c = Integer.parseInt(st.nextToken());
                graph[a][b]=c;
            }
            //점화식에 따라 플로이드 워셜 알고리즘 수행
            for(int k=1;k<=n;k++){
                for(int a=1;a<=n;a++){
                    for(int b =1;b<=n;b++){
                        graph[a][b]=Math.min(graph[a][b],graph[a][k]+graph[k][b]);
                    }
                }
            }
            //수행된 결과를 출력
            for(int a=1;a<=n;a++){
                for(int b=1;b<=n;b++){
                    if(graph[a][b]==INF){
                        System.out.print(-1+" ");
                    }
                    else
                        System.out.print(graph[a][b]+" ");
                }
                System.out.println();
            }
        }
    }
    반응형

    'Study Platform📚 > (알고리즘)- [이코테] 이것이 코딩테스트다 정리' 카테고리의 다른 글

    CHAPTER 6 -번외 정렬 - 위상 정렬(Topology Sort) - Python(파이썬)  (0) 2022.06.08
    [이코테] CHAPTER 09 최단 경로 알고리즘 - 다익스트라 최단 경로 알고리즘  (0) 2022.05.23
    [이코테] CHAPTER 05 DFS/BFS - BFS(deque 메서드) - Python(파이썬),Java(자바)  (0) 2022.05.18
    [이코테]CHAPTER 05 DFS/BFS - 스택, 큐, 재귀함수, DFS  (0) 2022.05.17
    [이코테] CHAPTER 06 정렬 - 계수 정렬  (0) 2022.05.16

    댓글

    이 글 공유하기

    • 구독하기

      구독하기

    • 카카오톡

      카카오톡

    • 라인

      라인

    • 트위터

      트위터

    • Facebook

      Facebook

    • 카카오스토리

      카카오스토리

    • 밴드

      밴드

    • 네이버 블로그

      네이버 블로그

    • Pocket

      Pocket

    • Evernote

      Evernote

    다른 글

    • CHAPTER 6 -번외 정렬 - 위상 정렬(Topology Sort) - Python(파이썬)

      CHAPTER 6 -번외 정렬 - 위상 정렬(Topology Sort) - Python(파이썬)

      2022.06.08
    • [이코테] CHAPTER 09 최단 경로 알고리즘 - 다익스트라 최단 경로 알고리즘

      [이코테] CHAPTER 09 최단 경로 알고리즘 - 다익스트라 최단 경로 알고리즘

      2022.05.23
    • [이코테] CHAPTER 05 DFS/BFS - BFS(deque 메서드) - Python(파이썬),Java(자바)

      [이코테] CHAPTER 05 DFS/BFS - BFS(deque 메서드) - Python(파이썬),Java(자바)

      2022.05.18
    • [이코테]CHAPTER 05 DFS/BFS - 스택, 큐, 재귀함수, DFS

      [이코테]CHAPTER 05 DFS/BFS - 스택, 큐, 재귀함수, DFS

      2022.05.17
    다른 글 더 둘러보기

    정보

    쿄코코 블로그의 첫 페이지로 이동

    쿄코코

    • 쿄코코의 첫 페이지로 이동

    검색

    메뉴

    • 홈

    카테고리

    • 분류 전체보기 (172)
      • Python (24)
        • 😈 99클럽 코테 스터디 4기 TIL (23)
        • 궁금한거 정리 (1)
      • SQL (16)
        • HackerRank (15)
      • [백준] Python,Java로 풀기📖 (71)
        • 정렬(Sorting) (6)
        • 그리디 (5)
        • 문자열 (7)
        • 수학 (3)
        • DFS&BFS (10)
        • 구현 (4)
        • 다이나믹 (17)
        • 이분탐색 (1)
        • 자료구조 (10)
        • 최단거리 (5)
        • 인덱스트리 (0)
      • [프로그래머스]Python,Java로 풀기 (6)
        • Level 1 (4)
        • Level 2 (2)
      • Study Platform📚 (28)
        • 김영한👨🏻‍🏫의 스프링 부트와 JPA 실무 완전 .. (5)
        • (알고리즘)- [이코테] 이것이 코딩테스트다 정리 (10)
        • 그림으로 배우는 Http&Network Basic (10)
        • AWS SAA C03공부하기 (3)
      • 까먹을까봐 적는 것들 (5)
      • 테스트 보고 난 후..🤔 (0)
      • kt 에이블스쿨 (18)

    최근 글

    인기 글

    댓글

    공지사항

    아카이브

    태그

    • TiL
    • 프로그래머스
    • 99클럽
    • 항해99
    • 백준
    • 티스토리챌린지
    • 오블완
    • 코딩테스트준비

    나의 외부 링크

    정보

    쿄코코의 쿄코코

    쿄코코

    쿄코코

    블로그 구독하기

    • 구독하기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. © 쿄코코. Designed by Fraccino.

    티스토리툴바