다익스트라 (Dijkstra) 최단 경로 알고리즘 (Graph)

  • 최초 작성일: 2023년 1월 13일(금)

목차

[TOC]

내용

개념

  • 가중치 값을 갖는 경로의 경우 사용할 수 있다.
  • 그 정보가 정말로 최단 거리라는 보장이 없기 때문에 미리 예약된 지점도 언제든지 뒤바뀔 수 있다.
  • 예약된 순서는 아무런 상관이 없고, 각 턴마다 그 상황에 맞는 best solution을 구한다.


실습

Dijistra 함수

  public void Dijikstra(int start)
  {
      bool[] visited = new bool[6];
      int[] distance = new int[6];

      Array.Fill(distance, Int32.MaxValue);

      distance[start] = 0;

      while (true)
      {
          // 제일 좋은 후보를 찾는다 (가장 가까이에 있는)

          // 가장 유력한 후보의 거리와 번호 저장
          int closest = Int32.MaxValue;
          int now = -1;
          for (int i = 0; i < 6; i++)
          {
              // 이미 방문한 정점 싑
              if (visited[i])
                  continue;

              // 아직 발견된 적이 없거나, 기존 후보보다 멀리 있으면 스킵
              if (distance[i] == Int32.MaxValue || distance[i] >= closest)
                  continue;

              // 여태껏 발견한 가장 좋은 후보라는 의미니까, 정보를 갱신
              closest = distance[i];
              now = i;
          }

          // 다음 후보가 하나도 없다 -> 종료
          if (now == -1)
              break;

          // 제일 좋은 후보를 찾았으니까 방문한다.
          visited[now] = true;

          // 방문한 정점과 인접한 정점들을 조사해서,
          // 상황에 따라 발견한 최단거리를 갱신한다.
          for (int next = 0; next < 6; next++)
          {
              // 연결되지 않은 정점 스킵
              if (adj[now, next] == -1)
                  continue;
              // 이미 방문한 정점은 스킵
              if (visited[next])
                  continue;

              // 새로 조사된 정점의 최단거리를 계산한다.
              int nextDist = distance[now] + adj[now, next];
              // 만약에 기존에 발견한 최단거리가 새로 조사된 최단거리보다 크면, 정보를 갱신
              if (nextDist < distance[next])
              {
                  distance[next] = nextDist;
              }
          }
      }
  }


풀소스

using System;
using System.Collections.Generic;

namespace MazeDijkstra
{
    class Graph
    {
        int[,] adj = new int[6, 6]
        {
            { -1, 15, -1, 35, -1, -1 },
            { 15, -1, 05, 10, -1, -1 },
            { -1, 05, -1, -1, -1, -1 },
            { 35, 10, -1, -1, 05, -1 },
            { -1, -1, -1, 05, -1, 05 },
            { -1, -1, -1, -1, 05, -1 },
        };

        public void Dijikstra(int start)
        {
            bool[] visited = new bool[6];
            int[] distance = new int[6];

            Array.Fill(distance, Int32.MaxValue);

            distance[start] = 0;

            while (true)
            {
                // 제일 좋은 후보를 찾는다 (가장 가까이에 있는)

                // 가장 유력한 후보의 거리와 번호 저장
                int closest = Int32.MaxValue;
                int now = -1;
                for (int i = 0; i < 6; i++)
                {
                    // 이미 방문한 정점 싑
                    if (visited[i])
                        continue;

                    // 아직 발견된 적이 없거나, 기존 후보보다 멀리 있으면 스킵
                    if (distance[i] == Int32.MaxValue || distance[i] >= closest)
                        continue;

                    // 여태껏 발견한 가장 좋은 후보라는 의미니까, 정보를 갱신
                    closest = distance[i];
                    now = i;
                }

                // 다음 후보가 하나도 없다 -> 종료
                if (now == -1)
                    break;

                // 제일 좋은 후보를 찾았으니까 방문한다.
                visited[now] = true;

                // 방문한 정점과 인접한 정점들을 조사해서,
                // 상황에 따라 발견한 최단거리를 갱신한다.
                for (int next = 0; next < 6; next++)
                {
                    // 연결되지 않은 정점 스킵
                    if (adj[now, next] == -1)
                        continue;
                    // 이미 방문한 정점은 스킵
                    if (visited[next])
                        continue;

                    // 새로 조사된 정점의 최단거리를 계산한다.
                    int nextDist = distance[now] + adj[now, next];
                    // 만약에 기존에 발견한 최단거리가 새로 조사된 최단거리보다 크면, 정보를 갱신
                    if (nextDist < distance[next])
                    {
                        distance[next] = nextDist;
                    }
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // DFS (Depth First Search 깊이 우선 탐색)
            // BFS (Breadth First Search 너비 우선 탐색)
            Graph graph = new Graph();
            graph.Dijikstra(0);
            //graph.SearchAll();

        }
    }
}