Tema1 Grafos2
Tema1 Grafos2
Tema1 Grafos2
Tema 1
TEORIA DE GRAFOS
1.1 DEFINICIÓN DE GRAFOS
1.2 CONCEPTOS
1.2.4 Conectividad
1.5 Aplicaciones
DESARROLLO
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Ejemplo:
Si 𝐺 = (𝑉, 𝐸) dónde:
𝑉 = {𝑣1 , 𝑣2 , 𝑣3 , 𝑣4 , 𝑣5 , 𝑣6 }
A continuación damos algunas definiciones para hacer una comparación. Sobre las siguientes:
Definición 1
En muchos casos los grafos simples no bastan para modelar algunos tipos de situaciones en las
cuales se requiere de la existencia de múltiples aristas entre par de vértices. En este caso no es
suficiente definir las aristas como par de vértices. A continuación veremos otras definiciones.
Definición 2
Definición 3
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Definición 4
Adyacencia
Dos vértices u, v de un grafo 𝐺 = (𝑉, 𝐸) se dicen adyacentes si (𝑢, 𝑣 ) ∈ 𝐸
Ejemplo
V1
(v1,v2)
(v1,v3)
V2
V3 (V3,v2)
Asimismo dos aristas son adyacentes si tienen un mismo vértice como extremo; análogamente
entre sí.
Incidencia
𝑒 = {𝑢, 𝑣 }𝑑𝑒𝑐𝑖𝑚𝑜𝑠 𝑞𝑢𝑒 𝑒𝑙 𝑙𝑎𝑑𝑜 𝑒 𝑒𝑠 𝑖𝑛𝑐𝑖𝑑𝑒𝑛𝑡𝑒 𝑎 𝑙𝑜𝑠 𝑣é𝑟𝑡𝑖𝑐𝑒𝑠 𝑢 𝑦 𝑣
∑ 𝑔𝑟(𝑢) = 2|𝐸|
𝑢∈𝑉
Ejemplo 2
Teniendo en cuenta las propiedades vistas, ¿es gráfica la sucesión (3,3,3,2,2)?
La sucesión de enteros no negativos (3,3,3,2,2) no es una sucesión gráfica
Porque no existe ningún grafo simple con un número impar de vértices de grado impar.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Ejemplo 3
¿Es gráfica la sucesión (6,3,3,2,2)?
La sucesión de enteros no negativos (6,3,3,2,2) no es una sucesión gráfica.
Porque si existiera un grafo no dirigido simple con esa sucesión de grados, tendría 5 vértices, uno
de los cuales tendría que estar conectado a 6 más, lo que significa que si el grafo ha de ser simple,
debería haber por lo menos 7 vértices.
Teorema de Hakimi
Sea la sucesión decreciente de enteros no negativos
𝑠, 𝑡1 , 𝑡2 , … 𝑡𝑠 , 𝑑1 , 𝑑2 , … , 𝑑𝑟
Se dice
(𝑠, 𝑡1 , 𝑡2 , … 𝑡𝑠 , 𝑑1 , 𝑑2 , … , 𝑑𝑟 ) es una sucesión gráfica si y solo si
(𝑡1 − 1, 𝑡2 − 1, … 𝑡𝑠 − 1, 𝑑1 , 𝑑2 , … , 𝑑𝑟 ) Es una sucesión gráfica
Cadena: 𝑣1 , 𝑣2 , 𝑣4 , 𝑣2 , 𝑣4
Cadena cerrada: 𝑣1 , 𝑣2 , 𝑣4 , 𝑣2 , 𝑣4 , 𝑣5 , 𝑣1
Camino: 𝑣1 , 𝑣2 , 𝑣4 , 𝑣3
Ciclo: 𝑣2 , 𝑣4 , 𝑣5 , 𝑣2
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
1.2.4 Conectividad
Conexión en grafos no dirigidos
Sea 𝐺 = (𝑉, 𝐸) grafo no dirigido
Se dice que el vértice 𝑢 está conectado a 𝑣 si 𝑢 𝑎𝑙𝑐𝑎𝑛𝑧𝑎 𝑎 𝑣.
Se llama componente conexa de G a todo subgrafo inducidos por los vértices de una clase de
equivalencia.
Se dice que es un grafo es conexo si tiene una única componente conexa.
Ejemplo:
Teorema 1
Sea 𝐺 = (𝑉, 𝐸) un grafo no dirigido, con |𝑉|>1
Si 𝐶𝑖 = (𝑉𝑖 , 𝐸𝑖 ), 𝑖 = 1,2, … 𝑟, 𝑟 > 0, son las componentes conexas de G, se verifica.
Teorema 2
Sea 𝐺 = (𝑉, 𝐸) un grafo no dirigido, conexo, |V|=n >1
A) G posee un ciclo o un vértice de grado 1
B) Si la arista 𝑒 = (𝑢, 𝑣) pertenece a un ciclo, entonces G-𝑒 es también conexo.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
c) |𝐸| ≥ |𝑉| − 1
Teorema 1
Sea 𝐺 = (𝑉, 𝐸) un grafo no dirigido, con |𝑉|>1
Si 𝐶𝑖 = (𝑉𝑖 , 𝐸𝑖 ), 𝑖 = 1,2, … 𝑟, 𝑟 > 0, son las componentes conexas de G, se verifica.
Teorema 2
Sea 𝐺 = (𝑉, 𝐸) un grafo dirigido, fuertemente conexo, |𝑉 | = 𝑛 > 1
|𝐸| ≥ |𝑉|
Grafo débilmente conexo
Sea 𝐺 = (𝑉, 𝐸) grafo dirigido
Se dice que el vértice u está débilmente conectado al 𝑣 si 𝑢 y 𝑣 están conectados en el grafo
subyacente 𝐺′.
Se llama componente débilmente conexa de G a todo subgrafo inducido por los vértices de una
clase de equivalencia, o de forma equivalente, a todo subgrafo tal que su subyacente sea una
componente conexa en 𝐺′.
Se dice que un grafo es débilmente conexo si su grafo subyacente es conexo.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
vértice.
Ejercicio: Un grafo completo con n vértices tiene 𝐶𝑛2 Aristas.
Grafos regulares
Sea un grafo 𝐺 = (𝑉, 𝐸) es regular de grado k o k-regular si cada vértice tiene grado k; es decir, un
grafo es regular si todos los vértices tiene el mismo grado.
Cabe resaltar algunos criterios para probar si un grafo es isomorfo, como ser el mismo número de
vértices, el mismo número de aristas, el mismo número de la misma cantidad de grados, el mismo
número de ciclos de cualquier longitud, etc.
Subgrafos
Sea 𝐺 = (𝑉, 𝐸) un grafo, Si 𝐻 = (𝑊, 𝐹) es un grafo tal que 𝑊 ⊆ 𝑉 𝑦 𝐹 ⊆ 𝐸 decimos que H es un
subgrafo de G.
Si F contiene todos los lados de E que unen los puntos de W en G se dice que H es un subgrafo
completo de G generado por W. Si W=V decimos que H es un subgrafo extendido de G.
Grafos Bipartitos
Se dice que un grafo simple 𝐺 = (𝑉, 𝐸) es bipartito si el conjunto de vértices V se puede dividir en
dos conjuntos disjuntos 𝑉1 , 𝑉2 , (𝑉1 ∪ 𝑉2 = 𝑉, 𝑉1 ∩ 𝑉2 = ∅) de tal manera que toda arista 𝑒 ∈ 𝐸
conecta un vértice 𝑉1 con un vértice de 𝑉2 .
Ejemplo
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
El problema se enuncia de la siguiente forma: Dos islas en el río Pregel, en Königsberg se unen
entre ellas y con la tierra firme mediante siete puentes. ¿Es posible dar un paseo empezando por
una cualquiera de las cuatro partes de tierra firme, cruzando cada puente una sola vez y volviendo
al punto de partida?
Por consiguiente la pregunta se traslada a “es posible pasar por todas las aristas sin repetir
ninguna”.
Euler demostró que no era posible ya que el número de aristas que inciden en cada vértice no es
par. “condición necesaria para entrar y salir de cada vértice y para regresar al punto de partida,
por caminos distintos”.
Si tenemos 𝐺 = (𝑉, 𝐸), si 𝐺 tiene exactamente dos vértices de grado impar, entonces 𝐺 tiene
camino euleriano.
En caso de que todos los vértices sean o tengan grado par, 𝐺 tiene un ciclo euleriano.
Propiedades
Un grafo conexo y no dirigido se dice que es euleriano si cada vértice tiene un grado par.
Un grafo no dirigido es euleriano si es conexo y si se puede descomponer en uno con los
vértices disjuntos.
Si un grafo no dirigido 𝐺 es euleriano entonces su gráfo-línea L(G) se dice que es también
euleriano.
Un grafo dirigido es euleriano si es conexo y cada vértice tiene grados internos iguales a
los externos.
Un grafo no dirigido se dice que es susceptible de ser recorrido (en inglés: traversable) si
es conexo y al menos dos vértices en el grafo tienen grado impar.
Grafo Hamiltonianos
Comencemos preguntándonos:
¿Cuándo un grafo tienen un ciclo cerrado qué contenga a todos sus vértices?
Cuando existe tal ciclo lo llamaremos ciclo hamiltoniano.
Definición
Tetraedro
Un camino hamiltoniano es un camino que pasa por cada vértice exactamente una vez. Un grafo
que contiene un camino hamiltoniano se denomina un ciclo hamiltoniano si es un ciclo que pasa
por cada vértice exactamente una vez (excepto el vértice del que parte y al cual llega). Un grafo
que contiene un ciclo hamiltoniano se dice grafo hamiltoniano.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
1.5 Aplicaciones
Un gran número de aplicaciones nace gracias a la teoría de grafos y continuamente se hallan
formas para resolver muchos problemas de la vida real aplicando grafos.
Por ejemplo existen aplicaciones de la síntesis de circuitos secuenciales, contadores o sistemas de
apertura.
Se puede usar para modelar trayectos como el de una línea de buses a través de las calles de una
ciudad, en la que podemos aplicar búsqueda de caminos para los trayectos.
Para la administración de proyectos como CMP y PERT, en las que se modelan los mismos usando
grafos.
La teoría de grafos también ha servido de inspiración para las ciencias sociales, en especial para
desarrollar un concepto no metafórico de red social que sustituye los nodos por los actores
sociales y verifica la posición, centralidad e importancia de cada actor dentro de la red. Esta
medida permite cuantificar y abstraer relaciones complejas, de manera que la estructura social
puede representarse gráficamente. Por ejemplo, una red social puede representar la estructura de
poder dentro de una sociedad al identificar los vínculos (aristas), su dirección e intensidad y da
idea de la manera en que el poder se transmite y a quiénes.
Los grafos son importantes en el estudio de la biología y hábitat. El vértice representa un hábitat y
las aristas (o "edges" en inglés) representa los senderos de los animales o las migraciones. Con
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
esta información, los científicos pueden entender cómo esto puede cambiar o afectar a las
especies en su hábitat.
También se ha usado los grafos para crear lenguajes cibernéticos aplicado a modelos continuos
como ser los diagramas de influencias propuestos por J w Forrester.
La aplicación se puede ver en cada día en el mundo real, ya que todo está conectado de alguna
manera y es parte de un sistema.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Tema Nº2
MODELO DE REDES
2.1 Introducción
2.4 Algoritmo
2.5.1 Dikjstra
2.5.1.1 Algoritmo
2.5.2 Floyd
2.5.2.1Algoritmo
2.6.1 Algoritmo
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Desarrollo:
Introducción
Existen multitud de situaciones modelables con grafos, o como redes. Algunas encuestas recientes
informan que hasta el 70% de los problemas de programación matemática en el mundo real se
pueden representar como modelos relacionados con redes.
1. Diseño de una red de gasoductos marinos para conectar bocas de pozos. “Como objetivo
por ejemplo, minimizar el costo de construcción”
2. Determinar la ruta más corta entre dos ciudades, en una red de carreteras.
3. Determinación de la capacidad máxima (en toneladas anuales) de una red de tubería para
lodo de carbón que une las minas en Wyoming con las centrales eléctricas en Houston.
La solución de estas situaciones y otras parecidas se logra con una variedad de algoritmos de
optimización de redes. Para lo cual veremos los siguientes algoritmos
Como ya vimos en el tema anterior definiremos los modelos basándonos en la teoría de grafos
donde reasentaremos los modelos como un conjunto de vértices y artistas, en su mayoría
haremos referencia a grafos dirigidos.
𝑁 = {1,2,3,4,5}
poblaciones puede pasar por uno o más poblaciones adicionales. El diseño más económico del
sistema de caminos indica que se minimice la distancia total de caminos pavimentados, resultado
que se obtiene implementando el algoritmo de árbol de expansión mínima.
̅
𝐶𝑘 = 𝐶𝑘−1 + {𝑗 ∗ }, 𝐶𝑘−1 − {𝑗 ∗ }
Si el conjunto 𝐶𝑘̅ de nodos conectados es vacío, detenerse. En cualquier otro caso, igualar 𝑘 = 𝑘 +
1 y repetir el paso.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
#
import numpy as nu
from StringIO import StringIO
class ArbolExpansionMinima():
matrizAdyacencia=[]
matrizResultados=[]
def __init__(self,matriz):
self.matrizAdyacencia=matriz
self.matrizResultados=[[0 for i in range(0,len(matriz))]for j in
range(0,len(matriz))]
def inicio_algoritmo(self):
self.listavacia=[]
self.listapermanente=[1,2,3,4,5,6,7,8,9]
elemento=self.listapermanente[0]
self.listavacia.append(elemento)
self.listapermanente.remove(elemento)
while len(self.listapermanente)!=0:
elemento=self.buscar()
self.listavacia.append(elemento)
self.listapermanente.remove(elemento)
for i in range(0,len(self.matrizAdyacencia)):
print self.matrizResultados[i]
def buscar(self):
minimo=999
index1=""
index2=""
for item in self.listavacia:
for item2 in self.listapermanente:
if(self.matrizAdyacencia[item-1][item2-1]!=9999):
if(self.matrizAdyacencia[item-1][item2-1]<minimo):
minimo=self.matrizAdyacencia[item-1][item2-1]
index1=item-1
index2=item2-1
self.matrizResultados[index1][index2]=self.matrizAdyacencia[index1][index2]
self.matrizResultados[index2][index1]=self.matrizAdyacencia[index1][index2]
return index2+1
class Main():
def __init__(self):
archivo=open("matrizAdyacencia.txt","r")
data=archivo.read()
archivo.close();
data_array=nu.genfromtxt(StringIO(data))
expansion=ArbolExpansionMinima(data_array)
expansion.inicio_algoritmo()
program=Main()
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Encontrar la ruta más corta de un punto a otro punto es uno de los más comunes, para tal efecto
se han creado numerosos algoritmos entre ellos “heurísticos”, en este caso nos enfocaremos en
los algoritmos más conocidos he importantes, pero antes de conocer estos algoritmos veamos
cómo podemos resolver este problema.
Ejemplo.
𝑉 = {𝑎, 𝑏, 𝑐, 𝑑, 𝑒, 𝑓, 𝑔, ℎ}
𝐸 = {(𝑎, 𝑐), (𝑎, 𝑏), (𝑏, 𝑒)(𝑏, ℎ), (ℎ, 𝑒), (ℎ, 𝑔), (𝑔, 𝑓), (𝑓, 𝑑), (𝑒, 𝑑), (𝑒, 𝑐), (𝑑, 𝑐)}
En los últimos años han ocurrido diversos accidentes en cada una de las rutas, donde las
probabilidades de accidentes se detallan en la siguiente tabla.
F-1 (f,d) 2%
E-1 (e,d) 0.5%
E-2 (e,c) 1%
D-1 (d,c) 2%
En base a esas estadísticas Miguel quien es una persona que quiere emprender un viaje con toda
su familia, quiere escoger la ruta más segura entre las ciudades a y g.
La solución a este problema puede ser encontrada fácilmente aplicando el siguiente algoritmo.
Algoritmo Dikjstra.
Este algoritmo permite encontrar la ruta más corta desde un Vértice seleccionado hacia todos los
demás.
Paso 0. Etiquetar el nodo fuente (nodo 1) con la etiqueta permanente [0,--]. Igualar 𝑖 = 1.
Paso i. a) Calcular las etiquetas temporales [𝑢𝑖 + 𝑑𝑖𝑗 , 𝑖] para cada nodo 𝑗 al que pueda llegarse
desde el nodo 𝑖, siempre y cuando 𝑗 no tenga etiqueta permanente. Si el nodo 𝑗 ya está
etiquetado con [𝑢𝑗 , 𝐾] por otro nodo 𝑘, y si 𝑢𝑗 + 𝑑𝑖𝑗 < 𝑢𝑗 sustituir [𝑢𝑗 , 𝑘]por [𝑢𝑗 + 𝑑𝑖𝑗 , 𝑖].
b) Si todos los nodos tienen etiquetas permanentes detenerse, en caso contrario seleccionar la
etiqueta [𝑢𝑖 , 𝑠] que tenga la distancia más corta (= 𝑢𝑟 ) entre todas las etiquetas temporales (los
empates se rompen en forma arbitraria). Hacer que 𝑖 = 𝑟 y repetir el paso 𝑖.
Para solucionar el problema planteado en la figura (), la red quedaría de la siguiente forma.
1 2
Etiquetamos con etiqueta permanente el nodo inicial 𝑎 De las etiquetas temporales buscamos el menor en este
[0, −−] y como a esta conectado con c y b, definimos caso es [3,a] en el vértice 𝑏 y lo convertimos en nuestro
las etiquetas Temporales [5,a], [3,a]. nodo permanente.
3 4
Seleccionamos la etiqueta menor en este caso tenemos Desde 𝑐 alcanzamos el nodo 𝑑 𝑦 𝑒 que no tienen y tiene
un empate con los vértices 𝑒, 𝑐 entonces hacemos una etiqueta temporal, en caso de d sumamos 5+2=7 y en
selección arbitraria. Tomaremos la etiqueta del vértice caso de e sumamos 5+1=6 como 6>5 no cambiamos la
c [5, 𝑎]. etiqueta temporal que ya tiene 𝑒.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
5 6
7 8
9 10
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
11 12
Escogemos el menor que es 7.5, se convierte en nuestra Finalmente terminamos el algoritmo, en G, ya que este
etiqueta permanente, y el camino hacia g mejora no puede conectarse con nadie más ya que ya no
porque 8.5<10 y reemplazamos existen etiquetas temporales.
Interpretación de resultados.
Las etiquetas nos dan toda información que necesitamos para resolver el problema.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Código en Python
from StringIO import StringIO
import numpy as num
import pdb
class Node:
indice="-"
pesosacumulados=0
estado=""
nodoid=0
def __main__():
cadena="\nEstado: "+estado+" id: "+nodoid
return cadena
class Djkstra:
matriz=[]
nodoActual=""
listadenodos=[]
def __init__(self,matriz):
self.matriz=matriz
def setNodoInicial(self,index):
for i in range(0,len(self.matriz)):
p=Node()
p.nodoid=i
self.listadenodos.append(p)
self.listadenodos[index].estado="Permanente"
self.listadenodos[index].nodoid=index
self.nodoActual=self.listadenodos[index]
def iniciarBusqueda(self):
while(self.existanNodosNoPermanentes()):
for i in range(0,len(self.matriz)):
idNodo=self.nodoActual.nodoid
if(self.matriz[idNodo][i]!=9999):
peso=self.matriz[idNodo][i]
nodoCompare=self.getNodo(i)
if(nodoCompare.estado!="Permanente"):
if(self.nodoActual.pesosacumulados+peso<nodoCompare.pesosacumulados or
nodoCompare.estado==""):
nodoCompare.pesosacumulados=self.nodoActual.pesosacumulados+peso
nodoCompare.indice=self.nodoActual.nodoid
nodoCompare.estado="no Permanente"
minimo=99999
aux=""
for i in range(0,len(self.matriz)):
if(self.listadenodos[i].estado=="no Permanente" and
self.listadenodos[i].pesosacumulados<minimo):
minimo=self.listadenodos[i].pesosacumulados
aux=self.listadenodos[i]
aux.estado="Permanente"
self.nodoActual=aux
for i in range(0,len(self.listadenodos)):
print
"["+str(self.listadenodos[i].indice)+","+str(self.listadenodos[i].pesosacumulados)+"]"
def getNodo(self,id):
for i in range(0,len(self.matriz)):
if(self.listadenodos[i].nodoid==id):
return self.listadenodos[i]
return False
def existanNodosNoPermanentes(self):
for i in range(0,len(self.listadenodos)):
if(self.listadenodos[i].estado!="Permanente"):
return True
return False
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
class Main:
def __init__(self):
archivo=open("matrizAdyacencia.txt","r")
data=archivo.read()
archivo.close()
matriz=num.genfromtxt(StringIO(data))
p=Djkstra(matriz)
p.setNodoInicial(0)
p.iniciarBusqueda()
programa=Main()
Algoritmo Floyd
El algoritmo Floyd es más general que Dijkstra, porque determina la ruta más corta entre
cualquiera de los vertices. El algoritmo representa una red de n nodos como matriz cuadrada de n
renglones y n columnas. El elemento (i,j) de la matriz expresa la distancia 𝑑𝑖𝑗 del vértice i al
vértice j , y es finita si el vértice esta conectado directamente con j, e infinita en caso contrario.
Definir las matrices iniciales de distancias 𝐷0 y de secuencias de nodos 𝑆0 como se describe abajo.
Los elementos diagonales se marcan con (0) para indicar que están bloqueados. Igualar 𝑘 = 𝑖.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Paso general K. Definir el renglón 𝑘 y la columna 𝑘 como renglón pivote y columna pivote. Aplicar
la operación triple a cada elemento 𝑑𝑖𝑗 en 𝐷𝑘−1 para toda 𝑖 y 𝑗. Si se satisface la condición.
𝑑𝑖𝑘 + 𝑑𝑘𝑗 < 𝑑𝑖𝑗 , (𝑖 ≠ 𝑘 𝑒 𝑖 ≠ 𝑗)
Hacer estos cambios
a) Crear 𝐷𝑘 reemplazando 𝑑𝑖𝑗 en 𝐷𝑘−1 por 𝑑𝑗𝑘 + 𝑑𝑘𝑗
b) Crear 𝑆𝑘 reemplazando 𝑆𝑖𝑗 en 𝑆𝑘−1 por 𝑘. Igualar 𝑘 = 𝑘 + 1 y repetir el paso 𝑘.
Ejemplo:
Aplicando el algoritmo Floyd en el ejemplo anterior
En este caso tenemos la iteración 0 con las matrices iniciales llamadas matriz de pesos y matriz de
recorrido.
Iteración 0
Iteración 1
Iteración 2
Iteración 3
Iteración 4
Iteración 5
Iteración 6
Iteración 7
import pdb
class floyd():
mainmatrix=[]
def __init__(self,matrix):
self.mainmatrix=matrix
def iniciar(self):
cn=len(self.mainmatrix)
path=self.mainmatrix;
#pdb.set_trace()
i=0
for r in range(0,cn):
path[i][i]=0
i+=1
rutas=[[0 for i in range(0,cn)]for j in range(0,cn)]
for r in range(0,cn):
for i in range(0,cn):
rutas[i][r]=r
for k in range(0,cn):
for i in range(0,cn):
for j in range(0,cn):
dt = path[i][k] + path[k][j]
if dt<path[i][j]:
rutas[i][j]=k
path[i][j]=dt
self.imprimir(path,rutas,k)
def imprimir(self,path,rutas,k):
paths=path
ruts=rutas
cn=len(path)
print "-----------------------------------------------------------------------\n"
print "Iteracion %s \n"%k
print "Matriz de Pesos Matriz de recorrido"
for i in range(0,cn):
cad="["
for j in range(0,cn):
n=len(str(paths[i][j]))
if n<3:
for kk in range(0,3-n):
cad+=" "
if j<cn-1:
cad+=str(paths[i][j])+","
else:
cad+=str(paths[i][j])
print "%s] | %s"%(cad,rutas[i])
#print "%s | %s"%(paths[i],rutas[i])
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Flujo máximo
Existe una diversidad de problemas donde lo impórtate es la cantidad de flujo que pasa a través de
cierta red.
Existen muchos problemas que se puede resolver conociendo el concepto de flujo máximo, este
depende naturalmente de los límites o capacidades de cada arco o arista, que son parte de la red.
Definamos algunos términos:
Definiciones básicas
Flujo: Cantidad de una sustancia que se transmite de un punto a otro sobre una unidad de tiempo.
Capacidad de flujo: es la cantidad máxima de flujo que puede ingresar atreves del nodo fuente y
salir por el nodo destino
Origen: es el vértice por el cual el flujo ingresa
Destino: es el vértice por el cual el flujo sale
Capacidades residuales: Capacidades restantes del arco una vez un flujo pasado por él.
Enumeración y cortes
Un cortede fine a un conjunto de arcos que, cuando se eliminan de la red, causan una interrupción
total del flujo entre los nodos fuente y sumidero. La capacidad de corte es igual a la suma de las
capacidades de los arcos correspondientes. Entre todos los cortes posibles en la red, el que tenga
la capacidad menor permite el flujo máximo en la red.
Ejemplo:
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Si hacemos estos cortes podemos determinar en base al siguiente criterio el flujo máximo de esta
red.
10+30+20 60
10+30+30+40 110
20+30+20 70
El flujo máximo llegaría a ser 60 la menor suma de todos los cortes posibles. No se puede decir
cuál es el flujo máximo en la red, a menos que se enumeren todos los cortes posibles. La única
información que se puede obtener de la enumeración parcial de los tres cortes es que el flujo
máximo en la red no puede ser mayor que 60 unidades. Desafortunadamente, enumerar todos los
cortes no es una tarea sencilla, y entonces se hace necesario desarrollar el eficiente algoritmo de
Paso 1.- Al nodo origen se le pone la etiqueta [-, ]; significa, a izquierda no hay inversos, a
derecha no hay límite de flujo. En este caso el nodo origen queda en el estado etiquetado y no
explorado, todos los otros nodos, no están etiquetados.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Igualar 𝑎𝑘 = 𝑐𝑖𝑘 y etiquetar el nodo 𝑘 con [𝑎𝑘 , 𝑖].Si 𝑘 = 𝑛, el nodo sumidero sea ha etiquetado, y
se ha encontrado una ruta de irrupción. Ir al paso 5. En caso contrario igualar 𝑖 = 𝑘 y seguir ene l
paso 2.
Paso 5. (𝐷𝑒𝑡𝑒𝑟𝑚𝑖𝑛𝑎𝑐𝑖𝑜𝑛 𝑑𝑒 𝑙𝑎 𝑟𝑒𝑑 𝑟𝑒𝑠𝑖𝑑𝑢𝑎𝑙) Sea 𝑁𝑝 = {1, 𝑘1 , 𝑘2 , 𝑘3 , 𝑛}; se definen los nodos de
la p-ésima ruta de irrupción del nodo fuente 1 al nodo sumidero 𝑛. Entonces el flujo máximo por la
ruta se calcula como
𝑓𝑝 = min{𝑎1 , 𝑎2 , … 𝑎𝑛 }
Se re instalan todos los nodos que se hayan eliminado en el paso 4. Poner 𝒊 = 𝟏 y regresar al paso
2 para intentar una nueva ruta de irrupción, repetir este proceso hasta que ya no existan rutas de
irrupción.
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
𝐹 = 𝑓1 + 𝑓2 + 𝑓3 + 𝑓4 + ⋯ 𝑓𝑚
Ejemplo de su aplicación.
Ejemplo:
Tres refinerías envían su producto de gasolina a dos terminales. La demanda que no se pueda
satisfacer se adquiere de otras fuentes. El producto de gasolina se transporta a las terminales por
medio de una red de conductos que son impulsados por tres estaciones de bombeo.
De A Capacidad De A Capacidad
R1 E1 20 E1 E3 10
R2 E1 35 E2 E3 30
R2 E2 45 E1 T1 10
R3 E3 15 E2 T2 30
E1 E3 20 E3 T1 50
E2 E1 10 E3 T2 20
Para un desarrollo correcto del algoritmo es necesario incluir un inicio y un fin con capacidades
infinitas, para que su valor no sea tomando en cuenta y será irrelevante dentro de la red.
PASO 5
Paso 5:
Traspaso de flujo:
Paso 5:
PASO 5:
Aquí podremos observar cómo se aplica el retroceso, la capacidad más grande en el vértice e2, es
30 el que conecta con e1, pero al tomar dicha conexión nos vemos obligados a retroceder porque
no tenemos irrupciones posibles en el vértice e1, así que regresamos a e2 y buscamos la irrupción
más próxima que es de 10 que conecta el vértice e2 con el e3.
Podemos ver en el gráfico que las capacidades de E1->F , E1->E3, E2->E3, E2->F, han llegado a su
límite ya que marcan 0, es ahí donde termina el algoritmo y el flujo máximo es la suma de:
𝐹 = {𝑓1 + 𝑓2 + 𝑓3 + 𝑓4 + 𝑓5 }=20+30+10+10+10=80
Investigación de operaciones 2 Ing. Ditmar David Castro Angulo
Interpretación de resultados
Tema 3