[Python] Graph

  1. Graph의 개념

    단순히 노드(N, node)와 그 노드를 연결하는 간선(E, Edge)을 하나로 모아 놓은 자료구조

    • 연결되어 있는 객체 간의 관계를 표현할 수 있는 자료구조임
    • 그래프는 여러 개의 고립된 부분 그래프로 구성될 수 있음

    💫 오일러 경로(Eulerian tour)
    ✅ 그래프에 존재하는 모든 간선을 한 번만 통과하면서 처음 정점으로 되돌아오는 경로
    ✅ 그래프의 모든 정점에 연결된 간선의 개수가 짝수일 때만 오일러 경로가 존재

  1. Graph와 관련된 용어

    정점위치라는 개념 ( ≒ node )
    간선위치 간의 관계 ( ≒ link, branch )
    인접 정점간선에 의해 직접 연결된 정점
    정점의 차수무방향 그래프에서 하나의 정점에 인접한 정점의 수
    → 무방향 그래프에 존재하는 정점의 모든 차수의 합
    = 그래프 간선 수의 2배
    진입 차수방향 그래프에서 외부에서 오는 간선의 수 ( ≒ 내차수 )
    진출 차수방향 그래프에서 외부로 향하는 간선의 수 ( ≒ 외차수 )
    → 방향 그래프에 있는 정점의 진입 차수 또는 진출 차수의 합
    = 방향 그래프의 간선의 수 ( 내차수 + 외차수 )
    경로 길이경로를 구성하는 데 사용된 간선의 수
    단순 경로경로 중에서 반복되는 정점이 없는 경우
    사이클단순 경로의 시작 정점과 종료 정점이 동일한 경우
  2. Graph의 특징

    • 그래프는 네트워크 모델임
    • 2개 이상의 경로가 가능함 → 노드들 사이에 무방향/방향에서 양방향 경로를 가질 수 있음
    • self-loop 뿐 아니라 loop/circuit 모두 가능함
    • 루트 노드라는 개념이 없음
    • 부모-자식 관계가 없음
    • 순회는 DFS나 BFS로 이루어짐
    • 그래프는 순환(Cyclic) 혹은 비순환(Acyclic)임
    • 그래프는 크게 방향 그래프와 무방향 그래프가 있음
    • 간선의 유무는 그래프에 따라 다름
  3. Graph의 종류

    • 무방향 그래프 (Undirected Graph)
      • 무방향 그래프의 간선은 간선을 통해서 양방향으로 갈 수 있음
      • 정점 A와 정점 B를 연결하는 간선은 (A,B)(A, B) 또는 (B,A)(B, A)와 같이 정점의 쌍으로 표현함
    • 방향 그래프 (Directed Graph)
      • 간선에 방향성이 존재하는 그래프
      • A → B로만 갈 수 있는 간선은 <A,B><A, B>
    • 가중치 그래프 (Weighted Graph)
      • 간선에 비용이나 가중치가 할당된 그래프
      • ‘네트워크’ 라고도 함
    • 연결 그래프 (Connected Graph)
      • 무방향 그래프에 있는 모든 정점 쌍에 대해서 항상 경로가 존재하는 경우
    • 비연결 그래프 (Disconnected Graph)
      • 무방향 그래프에서 특정 정점 쌍 사이에 경로가 존재하지 않는 경우
    • 순환 그래프 (Cyclic Graph)
      • 단순 경로의 시작 정점과 종료 정점이 동일한 경우 ( 단순 경로 : 경로 중에서 반복되는 정점이 없는 경우 )
    • 비순환 그래프 (Acyclic Graph)
      • 사이클이 없는 그래프
    • 완전 그래프 (Complete Graph)
      • 그래프에 속해 있는 모든 정점이 서로 연결되어 있는 그래프
      • 무방향 완전 그래프에서 정점 수가 nn이면 간선의 수는 n(n1)/2n*(n-1)/2
  4. Graph의 구현

    • 인접 리스트 (Adjacency List)
      • 각 정점에 인접한 정점들을 연결 리스트로 표현함
      • 파이썬은 포인터가 따로 존재하지 않으므로, 연결리스트를 구현하기 까다로움 ∴ 인접 리스트를 출발 노드를 키로, 도착 노드를 값으로 표현하는 딕셔너리 형태로 표현함, 도착 노드의 경우에는 여러 개의 노드가 가능하므로 값은 리스트 형태로 표현함
        graph = { 0 : [1],
        		  1 : [0, 2],
        		  2 : [] }
    • 인접 행렬 (Adjacency Matrix)
      • 정점의 개수를 k라고 했을 때, k*k matrix를 정의함
      • 각 row는 해당 정점의 연결 상태를 의함
      • 공간 복잡도는 O(N2)O(N^2)로 희소 그래프인 경우 매우 비효율적임 ∵ 인접 리스트는 어떤 노드에 인접한 노드들을 쉽게 찾을 수 있지만, 인접 행렬에서는 인접한 노드를 찾기 위해서는 모든 노드를 전부 순회해야 함
      • 무방향 그래프를 인접 행렬로 표현하면 이 행렬은 대칭 행렬이 됨
        • 물론 방향 그래프는 대칭 행렬이 안될 수도 있음
    • 인접 리스트 VS 인접 행렬
      • 인접 리스트
        • 그래프 내에서 적은 숫자의 간선만 가지는 희소 그래프의 경우
        • 장점
          1. 어떤 노드에 인접한 노드들을 쉽게 찾을 수 있음
          2. 그래프에 존재하는 모든 간선의 수는 O(N+E)O(N+E)
        • 단점
          1. 간선의 존재 여부와 정점의 차수 : 정점 i의 리스트에 있는 노드의 수 → 정점 차수만큼의 시간이 필요
      • 인접 행렬
        • 그래프에 간선이 많이 존재하는 밀집 그래프의 경우
        • 장점
          1. 두 정점을 연결하는 간선의 존재 여부를 O(1)O(1) 안에 즉시 알 수 있음
          2. 정점의 차수는 O(N)O(N) 안에 알 수 있음 → 인접 배열의 i번 째 행 또는 열을 모두 더함
        • 단점
          1. 어떤 노드에 인접한 노드들을 찾기 위해서는 모든 노드를 전부 순회해야 함
          2. 그래프에 존재하는 모든 간선의 수는 O(N2)O(N^2) 안에 알 수 있음 → 인접 행렬 전체를 조사함
  5. Graph의 탐색

    • DFS
      • 루트 노드에서 시작해서 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
      • 모든 노드를 방문하고자 할 때 이 방법을 선택함
    • BFS
      • 루트 노드에서 시작해서 인접한 노드를 먼저 탐색하는 방법
      • 두 노드 사이의 최단 경로 혹은 임의의 경로를 찾고 싶을 때 이 방법을 선택

➰ References

https://gmlwjd9405.github.io/2018/08/13/data-structure-graph.html

좋은 웹페이지 즐겨찾기