-
Notifications
You must be signed in to change notification settings - Fork 5
/
Dijkstra.py
62 lines (51 loc) · 1.94 KB
/
Dijkstra.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import networkx as nx
import numpy as n
import sys
def Dijkstra(G, s):
Lambda = {} # valores de "peso" para cada vértice
pred = {} # predecessores
Q = G.nodes() # vértices que ainda não estão na árvore de
# caminhos mínimos
# inicializamos todos os lambdas com infinito
for v in G.nodes():
Lambda[v] = n.inf
# Caso não haja pesos definidos para os vértices, atribuímos o valor 1
for v1,v2 in G.edges():
if ('weight' not in G[v1][v2]):
G[v1][v2]['weight'] = 1
Lambda[s] = 0
pred[s] = None
while Q:
# encontramos o menor valor de Lambda pertencente a Q
menor = n.inf
u = Q[0]
if sys.version_info[0] < 3:
for k,v in Lambda.iteritems():
if (v < menor) and (k in Q):
menor = v
u = k
else:
for k,v in Lambda.items():
if (v < menor) and (k in Q):
menor = v
u = k
# removemos o item de Q, já que está sendo inserido na árvore
u_index = Q.index(u)
del Q[u_index]
# percorremos a vizinhança de u procurando pesos menores
for v in G[u]:
if (v in Q) and (Lambda[v] > Lambda[u] + G[u][v]['weight']):
Lambda[v] = Lambda[u] + G[u][v]['weight']
pred[v] = u
# Criamos um novo grafo vazio do mesmo tipo de G
H = nx.create_empty_copy(G)
# Adicionamos os vértices de acordo com os dados de G
for v1,v2,data in G.edges(data=True):
if (pred[v2] is v1) or (pred[v1] is v2 and not nx.is_directed(H)):
H.add_edge( v1, v2, data )
H.node[v1]['lambda'] = Lambda[v1]
H.node[v2]['lambda'] = Lambda[v2]
# Retornamos a árvore de predecessores com a informação de Lambda[v]
return H