-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pruebas.py
162 lines (131 loc) · 4.55 KB
/
Pruebas.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# -*- coding: utf-8 -*-
"""
Libreria de grafos
Autor: Francisco Manuel Valle Ruiz
Última actualizacion: Ford Fulkerson
"""
import random
from collections import deque
from mvr_graph import *
from mvr_shortest_path import *
from mvr_edge_queue import *
from mvr_utils import *
from mvr_algorithms import *
##########################################
##########################################
##### #####
##### Recently added #####
##### #####
##########################################
##########################################
def FordFulkerson(G,a,z):
"""
<G> es una gráfica que cumple las caracteristicas de una
red de transporte/flujo (dirigida, ponderada no negativa)
Los 'pesos' de las aristas de G son las capacidades máximas
<a> y <z> son (strings representando) fuente y sumidero
respectivamente.
"""
def getCapacity(G,n1,n2):
return G.getWeight(n1,n2)
def nodos_entrantes(G, n1):
return [n for n in G if n1 in G.nodes[n]]
def actualizar_flujo(G,F,tags,a,z,x=None):
if x is None:
x = z
signo, k, _ = tags[x]
if signo == '+':
F[k,x] = F[k,x] + tags[z][2] # Revisar esta linea y la segunda siguiente: #ToCheck #ToDelete
elif signo == '-':
F[x,k] = F[x,k] - tags[z][2] #ToCheck #ToDelete
if k == a:
return True
else:
actualizar_flujo(G,F,tags,a,z,k)
return False
flujo_trivial = {(n,v): 0 for n in G for v in G.nodes[n]}
F = flujo_trivial
while(True):
tags = {} # diccionario de 3-tuplas conteniendo ('+'|'-', nombre de antecesor, flujo recibido)
tags[a] = ("+",a, float("inf"))
already_check = []
tagged = [a]
counter = 0
while counter < len(tagged):
# antes iteraba sobre los elementos de <tags>, pero como ocupo
# mutar sus elementos terminé optando por llevar una lista
# (para conservar el orden) de los elementos que se van agregando,
# a tags e iterar sobre la longitud de dicha lista, así puedo agregar
# tags sin problemas. Quizá esta medio cochino, pero it gets the work done
j = tagged[counter]
if j in already_check:
counter +=1
continue
for i in G.nodes[j]:
qji = getCapacity(G,j,i)
fji = F[(j,i)]
if i not in tags and fji < qji:
tags[i] = ('+', j ,min(tags[j][2], qji-fji))
tagged += i
for i in nodos_entrantes(G,j):
fij = F[(i,j)]
if i not in tags and fij > 0:
tags[i] = ('-', j , min(tags[j][2], fij))
tagged += i
# El nodo <j> se termino de examinar (todos sus vecinos tienen tag)
already_check += j
counter +=1
if z in tags: # Se encontró una cadena aumentante
actualizar_flujo(G,F,tags,a,z)
break
if z not in tags:
return F
assert True is False # Nunca se debería de llegar aquí. Algo está mal en el algoritmo.
##########################################
##########################################
##### #####
##### Testing #####
##### #####
##########################################
##########################################
"""
G = Graph("El 'Irene Ponderado'", directed = True)
G.addNodes(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"])
G.addEdge("A","F", 2)
G.addEdge("A","G", 6)
G.addEdge("B","A", 1)
G.addEdge("B","C", 1)
G.addEdge("B","E", 4)
G.addEdge("D","B", 2)
G.addEdge("D","F", 1)
G.addEdge("E","C", 4)
G.addEdge("E","D", 2)
G.addEdge("E","G", 1)
G.addEdge("E","L", 4)
G.addEdge("F","E", 2)
G.addEdge("G","H", 3)
G.addEdge("H","I", 2)
G.addEdge("I","K", 10)
G.addEdge("J","G", 1)
G.addEdge("J","K", 1)
G.addEdge("J","M", 2)
G.addEdge("L","F", 2)
G.addEdge("L","G", 5)
G.addEdge("L","J", 3)
G.addEdge("M","L", 1)
#G.addEdge("G","G", None)
print G
"""
G = Graph("La ciclo-negativa del desierto", directed = True)
G.addNodes(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
G.addEdge("A","B", 1)
G.addEdge("A","F", 1)
G.addEdge("B","C", 2)
G.addEdge("C","D", 2)
G.addEdge("C","F", 3)
G.addEdge("D","E", 3)
G.addEdge("F","G", 4)
G.addEdge("G","C", 1)
print "------- Ford Fulkerson -------"
D = FordFulkerson(G, 'A', 'E')
print D