포스트

(C#) 48. 다익스트라(Dijkstra) 최단 경로 알고리즘

Maze with Dijkstra Algorithm

(C#) 48. 다익스트라(Dijkstra) 최단 경로 알고리즘

(Dijkstra) (Graph)

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

##

##

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


##

Dijistra

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  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;
              }
          }
      }
  }


###

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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();

        }
    }
}

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.