프로그래밍공부(Programming Study)/이산 수학(Discrete Mathematis)

오일러 그래프에 관하여

Chaany 2024. 8. 18.
728x90

1. 오일러 그래프란?

오일러 그래프는 그래프 이론에서 중요한 개념 중 하나로, 그래프의 모든 변을 한 번씩만 지나서 처음 위치로 돌아오는 경로가 존재하는 그래프를 의미합니다. 이러한 경로를 오일러 경로라고 하며, 경로가 닫혀서 시작점으로 돌아오는 경우 이를 오일러 회로라고 부릅니다. 오일러 그래프의 이름은 이 개념을 처음으로 제시한 수학자 레온하르트 오일러(Leonhard Euler)에서 따왔습니다.

2. 오일러 그래프의 특징

오일러 그래프의 주요 특징은 다음과 같습니다:

  • 오일러 회로: 그래프의 모든 변을 한 번씩 지나 시작점으로 돌아오는 경로입니다.
  • 오일러 경로: 그래프의 모든 변을 한 번씩 지나지만, 시작점과 끝점이 다를 수 있는 경로입니다.
  • 조건:
    • 무향 그래프: 모든 정점의 차수가 짝수여야 오일러 회로가 존재합니다. 만약 두 개의 정점만 홀수 차수라면, 오일러 경로가 존재할 수 있습니다.
    • 유향 그래프: 각 정점에 대해 들어오는 변의 수와 나가는 변의 수가 동일해야 오일러 회로가 존재하며, 두 정점의 차이만 1이면 오일러 경로가 존재할 수 있습니다.
3. 오일러 그래프의 장단점

장점:

  • 그래프의 모든 변을 한 번씩만 지나가는 최적의 경로를 찾을 수 있어, 네트워크 최적화, 경로 탐색 등의 문제에서 유용합니다.
  • 역사적인 문제(예: 쾨니히스베르크의 다리 문제)를 푸는 데 중요한 역할을 했습니다.

단점:

  • 모든 그래프가 오일러 경로를 가지는 것은 아니며, 조건이 만족되지 않으면 사용할 수 없습니다.
  • 복잡한 그래프에서는 오일러 경로를 찾는 알고리즘이 비효율적일 수 있습니다.
4. 오일러 그래프의 구체적인 사례

쾨니히스베르크의 다리 문제는 오일러 그래프의 가장 유명한 예시입니다. 쾨니히스베르크 시내를 가로지르는 다리들을 한 번씩만 건너서 모든 다리를 다 건널 수 있는지의 문제로, 오일러는 이 문제를 통해 오일러 경로와 회로의 개념을 정립했습니다. 쾨니히스베르크의 다리는 오일러 회로를 형성하지 않으며, 오일러 경로도 존재하지 않음을 증명했습니다.

5. Python 코드 예제

아래는 간단한 무향 그래프에서 오일러 경로를 찾는 Python 코드 예제입니다.

from collections import defaultdict

class Graph:
    def __init__(self, vertices):
        self.graph = defaultdict(list)
        self.vertices = vertices

    def add_edge(self, u, v):
        self.graph[u].append(v)
        self.graph[v].append(u)

    def _dfs_count(self, v, visited):
        count = 1
        visited[v] = True
        for i in self.graph[v]:
            if not visited[i]:
                count += self._dfs_count(i, visited)
        return count

    def is_connected(self):
        visited = [False] * self.vertices
        for i in range(self.vertices):
            if len(self.graph[i]) > 0:
                break
        if i == self.vertices - 1:
            return True

        self._dfs_count(i, visited)
        for i in range(self.vertices):
            if visited[i] == False and len(self.graph[i]) > 0:
                return False
        return True

    def is_eulerian(self):
        if not self.is_connected():
            return 0

        odd = 0
        for i in range(self.vertices):
            if len(self.graph[i]) % 2 != 0:
                odd += 1

        if odd == 0:
            return 2  # 오일러 회로
        elif odd == 2:
            return 1  # 오일러 경로
        else:
            return 0  # 오일러 경로 없음

# 그래프 생성 및 엣지 추가
g = Graph(5)
g.add_edge(0, 1)
g.add_edge(1, 2)
g.add_edge(2, 3)
g.add_edge(3, 4)
g.add_edge(4, 0)

res = g.is_eulerian()

if res == 0:
    print("오일러 경로 없음")
elif res == 1:
    print("오일러 경로 존재")
else:
    print("오일러 회로 존재")
728x90

댓글