A010_FloydWarshall

2021. 11. 11. 14:24· Algorithms
 Warshall은 그래프에서 모든 쌍의 경로 존재 여부를 찾아내는 동적 계획 알고리즘을 제안하였고, Floyd는 이를 변형하여 모든 쌍 최단 경로를 찾는 알고리즘을 고안하였다. 그래서 모든 쌍 최단 경로를 찾는 동적 계획 알고리즘을 플로이드-워샬 알고리즘이라 한다. 
 플로이드 알고리즘의 시간복잡도는 O(n3)으로 다익스트라 알고리즘을 n번 사용할 때의 시간복잡도와 동일하지만 플로이드 알고리즘은 매우 간단하여 다익스트라 알고리즘을 사용하는 것보다 효율적이다.
 
플로이드 알고리즘은 모든 점을 경유 가능한 점들로 고려하면서 모든 쌍의 최단 경로의 거리를 계산한다. 이것은 점 1∼n까지의 모든 점을 경유 가능한 점들로 고려하면서, 모든 쌍의 최단 경로의 거리를 계산하는 것이다.
 

다음과 같은 입출력이 가능한 코드를 만들어보았다.

입력 : 2차원 배열 D, 단, D[i,j]=선분 (i,j)의 가중치, 만일 선분 (i,j)가 존재하지 않으면 D[i,j]=∞, 모든 i에 대하여 D[i,i]=0이다.

출력 :  모든 쌍 최단 경로의 거리를 저장한 2차원 배열 D

 

using System;

namespace FloydWarshall
{
  class Program
  {
    static int V = 5;  // Number of vertices
    const int Inf = 100;  // Infinity, not connected

    static void Main(string[] args)
    {
      int[,] graph = {
        { 0, 4, 2, 5, Inf },
        { Inf, 0, 1, Inf, 4 },
        { 1, 3, 0, 1, 2 },
        { -2, Inf, Inf, 0, 2 },
        { Inf, -3, 3, 1, 0 }
      };

      FloydWarshall(graph, V);
    }

    private static void FloydWarshall(int[,] graph, int V)
    {
      Console.WriteLine("graph");
      PrintDist(graph, V);

      int[,] next = new int[V, V];

      for (int i = 0; i < V; i++)
        for (int j = 0; j < V; j++)
          if (i != j)
            next[i, j] = j + 1;

      Console.WriteLine("next");
      PrintNext(next, V);

      for (int k = 0; k < V; k++)
      {
        for (int i = 0; i < V; i++)
          for (int j = 0; j < V; j++)
            if (graph[i,k] != Inf && graph[k,j] != Inf && 
              graph[i, k] + graph[k, j] < graph[i, j])
            {
              Console.WriteLine("Change: [{0},{1}] = [{2},{3}] + [{4},{5}] = {6}", 
                i, j, i, k, k, j, graph[i, k] + graph[k, j]);
              graph[i, j] = graph[i, k] + graph[k, j];
              next[i, j] = next[i, k];
            }

        Console.WriteLine("Dist({0})", k);
        PrintDist(graph, V);
        Console.WriteLine("Next({0})", k);
        PrintNext(next, V);
      }

      PrintResult(graph, next);
    }

    private static void PrintNext(int[,] next, int v)
    {
      for (int i = 0; i < v; i++) {
        for (int j = 0; j < v; j++)
          Console.Write("{0,8}", next[i, j]);
        Console.WriteLine();
      }
    }

    private static void PrintDist(int[,] graph, int V)
    {
      for (int i = 0; i < V; i++)
      {
        for (int j = 0; j < V; j++)
          Console.Write("{0,8}", graph[i, j]);
        Console.WriteLine();
      }
    }

    private static void PrintResult(int[,] graph, int[,] next)
    {
      // index는 0~V-1이고 Vertex는 1~V이므로 
      Console.WriteLine("pair     distance    path");
      for (int i = 0; i < V; i++)
        for (int j = 0; j < V; j++)
          if (i != j)
          {
            int u = i + 1;
            int v = j + 1;
            string path = string.Format("{0} -> {1}    {2,2:G}     {3}", u, v, graph[i, j], u);
            do
            {
              u = next[u - 1, v - 1];
              path += " -> " + u;
            } while (u != v);
            Console.WriteLine(path);
          }        
    }
  }
}
저작자표시 비영리 동일조건 (새창열림)

'Algorithms' 카테고리의 다른 글

백트래킹 기법  (0) 2021.11.29
그리디 알고리즘 - 부분 배낭 문제  (0) 2021.11.28
A008_Dijkstra  (0) 2021.10.21
A007_Prim  (0) 2021.10.12
A006_ClosestPair  (0) 2021.10.12
'Algorithms' 카테고리의 다른 글
  • 백트래킹 기법
  • 그리디 알고리즘 - 부분 배낭 문제
  • A008_Dijkstra
  • A007_Prim
페프
페프
페프
FFeFF SPACE
페프
전체
오늘
어제
  • 분류 전체보기
    • C++
      • Foundation
      • Programmers
    • C#
      • Foundation
      • Basics
    • Algorithms
    • SQLD
    • Web
      • JavaScript
    • AI-900
    • ETC

블로그 메뉴

  • About
  • 📗 Github
  • Programming_II
hELLO · Designed By 정상우.v4.2.2
페프
A010_FloydWarshall
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.