πŸšΆβ€β™‚οΈRoad to μ½”ν…Œ(12) - κ·Έλž˜ν”„

μ•ˆνƒœν˜„Β·2025λ…„ 4μ›” 25일

Algorithm

λͺ©λ‘ 보기
12/15
post-thumbnail

λ³Έ κ²Œμ‹œλ¬Όμ€ BaaarkingDogλ‹˜μ˜ μ‹€μ „ μ•Œκ³ λ¦¬μ¦˜ κ°•μ˜λ₯Ό 톡해 κ³΅λΆ€ν•œ 것을 μ •λ¦¬ν•©λ‹ˆλ‹€.

[μΆ”κ°€] μš©κ°ν•˜κ²Œ μ‹œμž‘ν•˜λŠ” μ½”λ”©ν…ŒμŠ€νŠΈ

[μΆ”κ°€] μ½”λ”© ν…ŒμŠ€νŠΈ ν•©κ²©μž 되기 - 파이썬

[μΆ”κ°€] 쒌좩우돌, 파이썬으둜 자료ꡬ쑰 κ΅¬ν˜„ν•˜κΈ°

[μΆ”κ°€] 개발자 남노씨 μ•Œκ³ λ¦¬μ¦˜ νŠΉκ°•.

κ·Έλž˜ν”„(Graph) 정리

κ·Έλž˜ν”„λŠ” ν˜„μ‹€ μ„Έκ³„μ˜ λ³΅μž‘ν•œ 관계λ₯Ό 효과적으둜 λͺ¨λΈλ§ν•  수 μžˆλŠ” λŒ€ν‘œμ μΈ μžλ£Œκ΅¬μ‘°μž…λ‹ˆλ‹€. μ•„λž˜λŠ” κ·Έλž˜ν”„μ˜ μ •μ˜, μ’…λ₯˜, ν™œμš©, 그리고 μ½”λ“œλ‘œ ν‘œν˜„ν•˜λŠ” λ°©λ²•κΉŒμ§€ ν•œλˆˆμ— μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

κ·Έλž˜ν”„μ˜ μ •μ˜

κ·Έλž˜ν”„(Graph)λŠ” 객체(λ…Έλ“œ, 정점)와 이듀 μ‚¬μ΄μ˜ μ—°κ²°(κ°„μ„ )둜 κ΅¬μ„±λœ μžλ£Œκ΅¬μ‘°μž…λ‹ˆλ‹€.
즉, 정점(Vertex, Node)의 μ§‘ν•© V와 κ°„μ„ (Edge)의 μ§‘ν•© E둜 이루어져 μžˆμŠ΅λ‹ˆλ‹€.
κ·Έλž˜ν”„λŠ” λΉ„μ„ ν˜• 자료ꡬ쑰둜, νŠΈλ¦¬λ³΄λ‹€ 더 λ‹€μ–‘ν•œ μ—°κ²° ꡬ쑰λ₯Ό ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν˜„μ‹€ μ„Έκ³„μ˜ 객체와 κ·Έ μ—°κ²° 관계λ₯Ό κ·Έλž˜ν”„ 자료ꡬ쑰둜 ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
κ°μ²΄λŠ” λ…Έλ“œ(정점), μ—°κ²° κ΄€κ³„λŠ” κ°„μ„ μœΌλ‘œ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ:
λ…Έλ“œ(정점): A, B, C, D, E, F
κ°„μ„ : A-B, B-C, B-E, C-D, E-D, E-F

κ·Έλž˜ν”„μ˜ ν™œμš© μ˜ˆμ‹œ

κ·Έλž˜ν”„λŠ” λ‹€μ–‘ν•œ λΆ„μ•Όμ—μ„œ ν™œμš©λ©λ‹ˆλ‹€:
ꡐ톡망/지도: λ„μ‹œ(정점), λ„λ‘œ(κ°„μ„ )
컴퓨터 λ„€νŠΈμ›Œν¬: 컴퓨터/λΌμš°ν„°(정점), μ—°κ²°(κ°„μ„ )
μ†Œμ…œ λ„€νŠΈμ›Œν¬: μ‚¬μš©μž(정점), 친ꡬ/νŒ”λ‘œμš°(κ°„μ„ )
λ„€λΉ„κ²Œμ΄μ…˜, μΆ”μ²œ μ‹œμŠ€ν…œ λ“±
κ·Έλž˜ν”„ 탐색 μ•Œκ³ λ¦¬μ¦˜(DFS, BFS λ“±)을 ν™œμš©ν•΄ μ΅œλ‹¨κ±°λ¦¬, 경둜 탐색, λ„€νŠΈμ›Œν¬ 뢄석 λ“± 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

κ·Έλž˜ν”„ μ’…λ₯˜

  1. 무방ν–₯ κ·Έλž˜ν”„(undirected graph) vs λ°©ν–₯ κ·Έλž˜ν”„(directed graph)
  • 무방ν–₯ κ·Έλž˜ν”„(Undirected Graph)

    - 간선에 λ°©ν–₯성이 μ—†λŠ” κ·Έλž˜ν”„μž…λ‹ˆλ‹€. 두 λ…Έλ“œλŠ” μ–‘λ°©ν–₯으둜 μ—°κ²°λ©λ‹ˆλ‹€.
    - Aβ†’B둜 갈 수 있으며, Bβ†’Aλ‘œλ„ 갈 수 μžˆμŠ΅λ‹ˆλ‹€. μ„œλ‘œ μ—°κ²°λœ μƒνƒœμž…λ‹ˆλ‹€.
    • λ°©ν–₯ κ·Έλž˜ν”„(Directed Graph)

간선에 λ°©ν–₯성이 있음. Aβ†’BλŠ” λ˜μ§€λ§Œ, Bβ†’AλŠ” 이동 λΆˆκ°€
  • 간선에 λ°©ν–₯성이 μžˆλŠ” κ·Έλž˜ν”„μž…λ‹ˆλ‹€. 간선이 Aμ—μ„œ B둜 ν–₯ν•˜λ©΄, Aμ—μ„œ B둜만 이동할 수 μžˆμŠ΅λ‹ˆλ‹€.
    - κ·Έλž˜ν”„λ₯Ό μžμ„Ένžˆ μ‚΄νŽ΄λ³΄λ©΄ λ“€μ–΄μ˜€λŠ” κ°„μ„ κ³Ό λ‚˜κ°€λŠ” κ°„μ„ μœΌλ‘œ ꡬ뢄할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ•Œ, λ“€μ–΄μ˜€λŠ” 간선을 indegree, λ‚˜κ°€λŠ” 간선을 outdegree라고 ν•©λ‹ˆλ‹€.
    - 예λ₯Ό λ“€μ–΄, 정점 Bλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ A와 Cλ‘œλΆ€ν„° λ“€μ–΄μ˜€λŠ” indegreeκ°€ 2개, E둜 λ‚˜κ°€λŠ” outdegreeκ°€ 1κ°œμž„μ„ μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.
  1. λ‹¨μˆœ vs 닀쀑
  • λ‹¨μˆœ

    - 자기 μžμ‹ μ„ μ—°κ²°ν•˜λŠ” κ°„μ„ (Self-loop)이 μ—†λŠ” κ·Έλž˜ν”„μž…λ‹ˆλ‹€
    - 두 정점 사이에 간선이 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•©λ‹ˆλ‹€.

3.κ°€μ€‘μΉ˜ κ·Έλž˜ν”„ vs λΉ„κ°€μ€‘μΉ˜ κ·Έλž˜ν”„

  1. μˆœν™˜ κ·Έλž˜ν”„ vs λΉ„μˆœν™˜ κ·Έλž˜ν”„
  • μˆœν™˜ κ·Έλž˜ν”„(Cyclic Graph)
    - 적어도 ν•˜λ‚˜ μ΄μƒμ˜ 사이클(μΆœλ°œν•œ μ •μ μœΌλ‘œ λ‹€μ‹œ λŒμ•„μ˜€λŠ” 경둜)이 μ‘΄μž¬ν•˜λŠ” κ·Έλž˜ν”„μž…λ‹ˆλ‹€.
    -λΉ„μˆœν™˜ κ·Έλž˜ν”„(Acyclic Graph)
    - 사이클이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” κ·Έλž˜ν”„λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.
    - λ°©λŒ€ν‘œμ μΈ 예둜 트리, λ°©ν–₯ λΉ„μˆœν™˜ κ·Έλž˜ν”„(DAG, Directed Acyclic Graph)κ°€ μžˆμŠ΅λ‹ˆλ‹€.

λ°©ν–₯ λΉ„μˆœν™˜ κ·Έλž˜ν”„(DAG, Directed Acyclic Graph)λž€ 말 κ·ΈλŒ€λ‘œ λ°©ν–₯성이 μžˆλŠ” κ·Έλž˜ν”„(Directed Graph) 쀑 사이클이 μ—†λŠ” κ·Έλž˜ν”„λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. DAGλŠ” μœ„μƒ μ •λ ¬(Topological Sorting)이 κ°€λŠ₯ν•˜λ©°, μž‘μ—… μŠ€μΌ€μ€„λ§, μ˜μ‘΄μ„± κ·Έλž˜ν”„, 컴파일러 μ΅œμ ν™” λ“±μ˜ λ¬Έμ œμ—μ„œ 자주 ν™œμš©λ©λ‹ˆλ‹€.

κ·Έλž˜ν”„μ˜ μš©μ–΄

  • 정점(Vertex, Node): 데이터λ₯Ό μ €μž₯ν•˜λŠ” λ‹¨μœ„
  • κ°„μ„ (Edge): 두 정점을 μ—°κ²°ν•˜λŠ” μ„ 
  • 인접(Adjacency): 두 정점이 간선을 톡해 μ—°κ²°λœ μƒνƒœ
  • 경둜(Path): 두 정점을 μž‡λŠ” κ°„μ„ μ˜ μˆœμ„œ
  • 사이클(Cycle): μ‹œμž‘ μ •μ μœΌλ‘œ λ‹€μ‹œ λŒμ•„μ˜€λŠ” 경둜
  • 차수(Degree): 정점에 μ—°κ²°λœ κ°„μ„ μ˜ 개수 (λ°©ν–₯ κ·Έλž˜ν”„μ—μ„œλŠ” μ§„μž…μ°¨μˆ˜/μ§„μΆœμ°¨μˆ˜λ‘œ ꡬ뢄)

κ·Έλž˜ν”„μ˜ ν‘œν˜„ 방법 (μ½”λ“œ κ΅¬ν˜„)

κ·Έλž˜ν”„λ₯Ό μ½”λ“œλ‘œ ν‘œν˜„ν•˜λŠ” λŒ€ν‘œμ μΈ 방법은 μ„Έ κ°€μ§€μž…λ‹ˆλ‹€:

  1. 인접 ν–‰λ ¬ (Adjacency Matrix)
    2차원 λ°°μ—΄λ‘œ λ…Έλ“œ κ°„ μ—°κ²° 관계λ₯Ό ν‘œν˜„
    μ—°κ²°λ˜μ–΄ 있으면 1(λ˜λŠ” κ°€μ€‘μΉ˜), μ•„λ‹ˆλ©΄ 0
int[][] matrix = {
    {0, 1, 0, 0, 0, 0}, // A
    {1, 0, 1, 0, 1, 0}, // B
    {0, 1, 0, 1, 0, 0}, // C
    {0, 0, 1, 0, 1, 1}, // D
    {0, 1, 0, 1, 0, 1}, // E
    {0, 0, 0, 1, 1, 0}, // F
};

μž₯점: κ°„μ„  쑴재 μ—¬λΆ€λ₯Ό μ¦‰μ‹œ 확인 κ°€λŠ₯
단점: 정점 μˆ˜κ°€ 많고 간선이 적은 경우(ν¬μ†Œ κ·Έλž˜ν”„) λ©”λͺ¨λ¦¬ λ‚­λΉ„κ°€ 큼

  1. 인접 리슀트 (Adjacency List)
    각 정점이 μ—°κ²°λœ 정점 λͺ©λ‘μ„ 리슀트(ν˜Ήμ€ λ§΅)둜 μ €μž₯
    ν¬μ†Œ κ·Έλž˜ν”„μ—μ„œ λ©”λͺ¨λ¦¬ 효율적

μž₯점: λ©”λͺ¨λ¦¬ 효율적, λ…Έλ“œ μΆ”κ°€/μ‚­μ œ 용이
단점: μ—°κ²° μ—¬λΆ€ 확인은 인접 행렬보닀 느릴 수 있음

Map<String, List<String>> graph = new HashMap<>() {{
    put("A", List.of("B"));
    put("B", List.of("A"));
    put("C", List.of());
    put("D", List.of());
    put("E", List.of());
    put("F", List.of());
}};
  1. μ•”μ‹œμ  κ·Έλž˜ν”„ (Implicit Graph)
    λ…Έλ“œμ™€ 간선을 λͺ…μ‹œμ μœΌλ‘œ μ €μž₯ν•˜μ§€ μ•Šκ³ , κ·œμΉ™μ΄λ‚˜ μˆ˜μ‹μœΌλ‘œ μ—°κ²° 관계λ₯Ό μ •μ˜
    예: 2차원 λ°°μ—΄μ—μ„œ μƒν•˜μ’Œμš° 이동, 퍼즐 문제 λ“±
    μ’Œν‘œ μƒμ—μ„œ dfs/bfsν•˜λŠ” 것. 0,1 νŒλ‹¨ν•˜λŠ” 것.

인접 리슀트 λ³€ν™˜ 방법

  • case1) κ°„μ„  정보가 μž…λ ₯κ°’μœΌλ‘œ λ‚˜μ˜¬ λ•Œ

λ¬Έμ œμ—μ„œ κ°„μ„  정보(edges)κ°€ μ£Όμ–΄μ§ˆ λ•Œ, 이λ₯Ό 인접 리슀트(list)둜 λ³€ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€

edges = [[0, 1], [0, 3], [0, 6], [1, 3], [2, 3], [3, 7], [4, 5], [5, 6], [5, 7]]
n = 8 # λ…Έλ“œμ˜ 개수

인접 리슀트 λ³€ν™˜ μ½”λ“œ

// 인접 리슀트 μ΄ˆκΈ°ν™”
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
    graph.add(i, new ArrayList<>()); // 각 λ…Έλ“œμ— λŒ€ν•΄ 빈 리슀트 μΆ”κ°€
}

// μ–‘λ°©ν–₯ κ°„μ„  μΆ”κ°€
for (int[] edge : edges) {
    int a = edge[0];
    int b = edge[1];

    graph.get(a).add(b); // a -> b μ—°κ²°
    graph.get(b).add(a); // b -> a μ—°κ²° (μ–‘λ°©ν–₯)
}

일방ν–₯ κ·Έλž˜ν”„μΈ 경우

λ§Œμ•½ λ¬Έμ œμ—μ„œΒ μΌλ°©ν–₯ κ·Έλž˜ν”„λΌκ³  λͺ…μ‹œλ˜μ—ˆλ‹€λ©΄, λ‹€μŒκ³Ό 같이 λ³€ν™˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

// 인접 리슀트 μ΄ˆκΈ°ν™”
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
    graph.add(new ArrayList<>()); // 각 λ…Έλ“œμ— λŒ€ν•΄ 빈 리슀트 μΆ”κ°€
}

// 일방ν–₯ κ°„μ„  μΆ”κ°€
for (int[] edge : edges) {
    int a = edge[0];
    int b = edge[1];

    graph.get(a).add(b); // a -> b μ—°κ²°
}
  • case2) 인접 리슀트(list)λ₯Ό μž…λ ₯값을 쀄 λ•Œ
    일뢀 λ¬Έμ œμ—μ„œλŠ”Β μ΄λ―Έ 인접 리슀트(list) ν˜•νƒœλ‘œ μž…λ ₯이 μ œκ³΅λ˜κΈ°λ„ ν•©λ‹ˆλ‹€.
List<List<Integer>> graph = new ArrayList<>() {{
    add(List.of(1, 3, 6));
    add(List.of(0, 3));
    add(List.of(3));
    add(List.of(0, 1, 2, 7));
    add(List.of(5));
    add(List.of(4, 6, 7));
    add(List.of(0, 5));
    add(List.of(3, 5));
}};
profile
κ³ κ°μ—κ²Œ μ‹ λ’°λ₯Ό λ§Œλ“œλŠ” λ°±μ—”λ“œ 개발자 μ•ˆνƒœν˜„μž…λ‹ˆλ‹€.

0개의 λŒ“κΈ€