김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Remote저장소
  • local저장소
  • GitHubDesktop
  • 깃허브데스크탑
  • 원격저장소
  • KMU_WINK
  • ㄱ
  • 로컬저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[알고리즘] 다익스트라(Dijkstra Algorithm) 알고리즘 파이썬, 최소힙(min-heap) 사용하기
•알고리즘(Algorithm )/스터디

[알고리즘] 다익스트라(Dijkstra Algorithm) 알고리즘 파이썬, 최소힙(min-heap) 사용하기

2022. 7. 28. 03:06

# 파이썬 언어

# 무한대값 만들기
CONST_INFINITE = float('inf')
import heapq

# heapq라이브러리를 사용하여 최소 힙 만들기
min_heap = []

# push O(log n)
heapq.heappush(min_heap,[10,'A'])

# pop O(1)
heapq.heappop(min_heap)

 heapq에서는 최소힙만 지원하기 때문에, max_heap을 사용하기 위해서는 값을 insert할때 ' - '을 곱해주고 꺼낼때 다시 ' - '를 곱하는 편법을 이용한다고 한다. 뭐 우선순위 큐에서 람다식으로 우선순위를 정해주는 방법도 있을거 같기는 하다. 

# 사용된 그래프

# 설명

 학교에서 자료구조시간에 다익스트라 알고리즘을 배울때는, 힙을 사용하지 않는 방법에 대해서 공부했었다. 배열을 읽고 배열에서 가장 작은 노드를 뽑아서 구현하는 방식을 사용했었는데, 힙을 사용하니 편하게 구현 할 수 있었다.

 BFS와 유사한 방식으로 진행되어 나간다. 힙에 해당 노드까지의 최신화 된 거리(weight)를 기록해 둔 후, 하나씩 pop하고 인접노드들 + 현재 거리의 값을 현재 distance_state와 비교해서 작은 update를 시켜주는 방식을 사용한다. 

 

# 코드

import heapq

CONST_INFINITE = float('inf')

def make_graph():
  graph = {
    'A': {'B': 8, 'C': 1, 'D': 2},
    'B': {},
    'C': {'B': 5, 'D' : 2},
    'D': {'E': 3, 'F': 5},
    'E': {'F': 1},
    'F': {'A': 5}
    }

  return graph

def dijstra(graph, start):
  min_queue = []
  distance_state = {node: CONST_INFINITE for node in graph}

  # 초기화 해주기
  distance_state[start] = 0
  heapq.heappush(min_queue, [distance_state[start], start])
  print(f"__init__ {distance_state}")

  # 힙에서 꺼내오고 비교하기
  while min_queue:
    cur_distance, cur_node = heapq.heappop(min_queue)  # ex) [ 0 : 'A']
    # 이미 최단경로이면 검사할 필요가 없음
    if cur_distance > distance_state[cur_node] :
      continue

    for adjacent_node, weight in graph[cur_node].items() :
      if distance_state[adjacent_node] > cur_distance + weight :
        # update
        update_weight = cur_distance + weight
        distance_state[adjacent_node] = update_weight
        heapq.heappush(min_queue,[update_weight,adjacent_node])
    print(f"distance_state = {distance_state} cur_node : {cur_node}")

  return distance_state


if __name__ == '__main__':
  start = 'A'
  data = make_graph()
  result = dijstra(data,start)

  print(f"\nresult : {result}")

 

# 참고

E = Edge

일단 모든 간선을 하나씩 순회하면서 탐색해야하기 때문에 O(E)의 시간이 걸린다.

힙을 insert할때 O(log n)만큼의 시간이 걸리는것을 생각해 봤을때를 생각해야 하기때문에 시간복잡도는 아래와 같다

저작자표시 (새창열림)

'•알고리즘(Algorithm ) > 스터디' 카테고리의 다른 글

[알고리즘] 프림(Prim's) 알고리즘 파이썬, 최소신장트리(MST) 찾기, 파이썬 heapq, defaultdic  (0) 2022.07.30
[알고리즘] 크루스칼(Kruskal) 알고리즘 파이썬, 최소신장트리(MST), union-find기법(union-by-rank, path-compression)  (0) 2022.07.30
[알고리즘] DFS(깊이 우선 탐색) 파이썬  (0) 2022.07.27
[알고리즘] BFS(넓이 우선탐색) 파이썬 구현 , 파이썬으로 그래프 노드 표현하기  (0) 2022.07.27
[알고리즘] 순차탐색 파이썬 시간복잡도  (0) 2022.07.26
    '•알고리즘(Algorithm )/스터디' 카테고리의 다른 글
    • [알고리즘] 프림(Prim's) 알고리즘 파이썬, 최소신장트리(MST) 찾기, 파이썬 heapq, defaultdic
    • [알고리즘] 크루스칼(Kruskal) 알고리즘 파이썬, 최소신장트리(MST), union-find기법(union-by-rank, path-compression)
    • [알고리즘] DFS(깊이 우선 탐색) 파이썬
    • [알고리즘] BFS(넓이 우선탐색) 파이썬 구현 , 파이썬으로 그래프 노드 표현하기
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바