|
1 |
| -# Grafos - Algoritmos de Dijkstra em Python |
2 |
| -# Bruno Dantas de Paiva - 2021 |
3 |
| -# https://github.com/DantasB |
4 |
| - |
5 | 1 | import heapq
|
6 | 2 |
|
7 | 3 |
|
8 |
| -class Grafo: |
9 |
| - """Define um grafo utilizando matriz de adjacências. |
10 |
| -
|
11 |
| - Args: |
12 |
| - arestas (list): uma lista de listas onde o indice é o |
13 |
| - vértice e cada elemento da lista é o vizinho |
14 |
| - """ |
15 |
| - |
16 |
| - def __init__(self, arestas: list): |
17 |
| - self.adj = [[] for _ in range(len(arestas))] |
18 |
| - self.dist = [99999 for _ in range(len(arestas))] |
19 |
| - self.adiciona_arestas(arestas) |
20 |
| - |
21 |
| - def adiciona_arestas(self, arestas: list) -> None: |
22 |
| - """Adiciona todas as arestas ao grafo |
23 |
| -
|
24 |
| - Args: |
25 |
| - arestas (list): a lista contendo todas as definições de arestas do grafo |
26 |
| - """ |
27 |
| - for i in range(len(arestas)): |
28 |
| - for j in range(len(arestas[i])): |
29 |
| - self.__adiciona_aresta(i, arestas[i][j]) |
| 4 | +class Graph: |
| 5 | + def __init__(self, edges: list): |
| 6 | + self.adj = [[] for _ in range(len(edges))] |
| 7 | + self.dist = [99999 for _ in range(len(edges))] |
| 8 | + self.add_edges(edges) |
30 | 9 |
|
31 |
| - def __adiciona_aresta(self, u: int, v: int) -> None: |
32 |
| - """Adiciona a aresta na matriz de adjacência |
| 10 | + def add_edges(self, edges: list) -> None: |
| 11 | + for i in range(len(edges)): |
| 12 | + for j in range(len(edges[i])): |
| 13 | + self.__add_edge(i, edges[i][j]) |
33 | 14 |
|
34 |
| - Args: |
35 |
| - u (int): vértice u |
36 |
| - v (int): vértice v |
37 |
| - """ |
| 15 | + def __add_edge(self, u: int, v: int) -> None: |
38 | 16 | if v[0] not in self.adj[u]:
|
39 | 17 | self.adj[u].append([v[1], v[0]])
|
40 | 18 |
|
41 |
| - def _peso_entre_u_e_v(self, u: int, v: int) -> float: |
42 |
| - """Retorna o peso entre os vértices u e v |
43 |
| -
|
44 |
| - Args: |
45 |
| - u (int): vértice u |
46 |
| - v (int): vértice v |
47 |
| -
|
48 |
| - Returns: |
49 |
| - float: peso entre u e v |
50 |
| - """ |
51 |
| - for vertice in self.adj[v[1]]: |
52 |
| - if vertice[1] == u: |
53 |
| - return vertice[0] |
| 19 | + def _weight_between_u_and_v(self, u: int, v: int) -> float: |
| 20 | + for vertex in self.adj[v[1]]: |
| 21 | + if vertex[1] == u: |
| 22 | + return vertex[0] |
54 | 23 |
|
55 | 24 | def dijkstra(self, start: int) -> list:
|
56 |
| - """Retorna a lista de distância do vértice start até todos os vértices |
57 |
| -
|
58 |
| - Args: |
59 |
| - start (int): vértice inicial |
60 |
| -
|
61 |
| - Returns: |
62 |
| - list: lista de distâncias |
63 |
| - """ |
64 |
| - distancia = self.dist.copy() |
65 |
| - S = set() # Conjunto de vértices explorados |
66 |
| - distancia[start] = 0 |
| 25 | + distance = self.dist.copy() |
| 26 | + S = set() # Set of explored vertices |
| 27 | + distance[start] = 0 |
67 | 28 |
|
68 | 29 | while True:
|
69 |
| - V = set([(i, distancia[i]) for i in range(len(self.adj))]) |
70 |
| - diferenca_de_conjuntos = list(V.difference(S)) |
71 |
| - if not diferenca_de_conjuntos: |
| 30 | + V = set([(i, distance[i]) for i in range(len(self.adj))]) |
| 31 | + difference_of_sets = list(V.difference(S)) |
| 32 | + if not difference_of_sets: |
72 | 33 | break
|
73 | 34 |
|
74 |
| - heapq.heapify(diferenca_de_conjuntos) |
75 |
| - u, distancia_u = heapq.heappop(diferenca_de_conjuntos) |
| 35 | + heapq.heapify(difference_of_sets) |
| 36 | + u, distance_u = heapq.heappop(difference_of_sets) |
76 | 37 |
|
77 |
| - S.add((u, distancia[u])) |
| 38 | + S.add((u, distance[u])) |
78 | 39 | for v in self.adj[u]:
|
79 |
| - if distancia[v[1]] > distancia_u + self._peso_entre_u_e_v(u, v): |
80 |
| - distancia[v[1]] = distancia_u + self._peso_entre_u_e_v(u, v) |
| 40 | + if distance[v[1]] > distance_u + self._weight_between_u_and_v(u, v): |
| 41 | + distance[v[1]] = distance_u + self._weight_between_u_and_v(u, v) |
81 | 42 |
|
82 |
| - return distancia |
| 43 | + return distance |
83 | 44 |
|
84 | 45 |
|
85 |
| -arestas = [ |
86 |
| - [[1, 1], [2, 0.3], [5, 0.2]], # Vizinhos do vértice 0. |
87 |
| - [[0, 1], [2, 0.5]], # Vizinhos do vértice 1. |
88 |
| - [[0, 0.3], [1, 0.5], [3, 1.5], [4, 2]], # Vizinhos do vértice 2. |
89 |
| - [[2, 1.5], [4, 1.3], [5, 0.8]], # Vizinhos do vértice 3. |
90 |
| - [[2, 2], [3, 1.3]], # Vizinhos do vértice 4. |
91 |
| - [[0, 0.2], [3, 0.8]], # Vizinhos do vértice 5. |
92 |
| -] |
| 46 | +if __name__ == "__main__": |
| 47 | + edges = [ |
| 48 | + [[1, 1], [2, 0.3], [5, 0.2]], # Neighbors of vertex 0. |
| 49 | + [[0, 1], [2, 0.5]], # Neighbors of vertex 1. |
| 50 | + [[0, 0.3], [1, 0.5], [3, 1.5], [4, 2]], # Neighbors of vertex 2. |
| 51 | + [[2, 1.5], [4, 1.3], [5, 0.8]], # Neighbors of vertex 3. |
| 52 | + [[2, 2], [3, 1.3]], # Neighbors of vertex 4. |
| 53 | + [[0, 0.2], [3, 0.8]], # Neighbors of vertex 5. |
| 54 | + ] |
93 | 55 |
|
94 |
| -grafo = Grafo(arestas) |
95 |
| -print(grafo.dijkstra(0)) |
| 56 | + graph = Graph(edges) |
| 57 | + print(graph.dijkstra(0)) |
0 commit comments