Documente Academic
Documente Profesional
Documente Cultură
Sección: 503
Matrı́cula: 0300704C
11 de enero de 2011
1
Tarea:
El algoritmo de Floyd-Warshall
2
y
(k) wij k=0
dij = (k−1) (k−1) (k−1)
min(dij , dik + dkj ) k≥1
ahora para saber como se altera la matriz de predecesores, podemos dar una
(k)
formulación recursiva de Πij . Cuando k = 0, una ruta mas corta de i hasta
j no tiene vertices intermedios en absoluto. Por lo tanto,
(0) N IL if i = j or wij = ∞
Πij =
i if i 6= j and wij < ∞
Algoritmo de Floyd-Warshall.
pseudocodigo
FLOYD-WARSHALL(W )
1: n ← rows[W ]
2: D(0) ← W
3: para k ← 1 hasta n hacer
4: para i ← 1 hasta n hacer
5: para j ← 1 hasta n hacer
(k) (k−1) (k−1) (k−1)
6: dij ← min(dij , dik + dkj )
7: fin para
8: fin para
9: fin para
10: regresa D(n)
11: regresa Π(n)
3
Se propone el siguiente codigo en C++, floyd warshall.cpp:
#include< iostream >
#include< climits >
#include< cstdlib >
#include< cstdio >
//definiciones para el algoritmo
#define INF 10000000
#define NIL -1
using namespace::std;
4
int main(){
int narist;
int a, b, c;
5
en la figura 2 podemos ver una corrida de la forma en que trabaja el algoritmo
de Floyd-Warshall:
6
ahora ejecutando el archivo floyd warshall.cpp:
7
b) Programar la solución para el problema del flujo máximo
* Utilizar el método de Ford-Fulkerson
El algoritmo de Ford-Fulkerson
8
En cada iteración del método de Ford-Fulkerson, encontramos algunas
rutas p que aumentan e incrementan el flujo f en cada vertice de p por la ca-
pacidad residual cf (p). La consecuencia de la aplicación del método calcula el
caudal máximo en un grafo G = (V, E), poniendo al dı́a el flujo f [u, v] entre
cada par u, v de vertices que estan conectados por una vertice. Si u y v no
estan conectados por una arista en cualquier dirección, se supone implı́cita-
mente que f [u, v] = 0. La capacidad de c(u, v) se supone que se administra
junto con el grafo, y c(u, v) = 0 si (u, v) E.
Algoritmo de Ford-Fulkerson.
pseudocodigo
FORD-FULKERSON(G,s,t)
1: para cadavertice(u, v)E[G] hacer
2: f [u, v] ← 0
3: f [v, u] ← 0
4: mientras existaunarutapdeshastatenlaredresidualGf hacer
5: cf (p) ← min{cf (u, v) : (u, v)estaenp}
6: para cadavertice(u, v)enp hacer
7: f [u, v] ← f [u, v] + cf (p)
8: f [v, u] ← −f [u, v]
9: fin para
10: fin mientras
9
Se propone el siguiente codigo en C++, ford fulkerson.cpp:
#include < stdio.h >
#include < list >
//definiciones para el algoritmo
#define MAXVERT 100
#define NULO -1
#define INFINITO 100000000
using namespace::std;
10
for(int i = 0; i < nvert; i + +)
for(int j = 0; j < nvert; j + +)
grafo[i][j].flujo = 0;
flujomax = 0;
//mientras existan caminos de flujo residual
while(BFS(fuente, sumidero)){
//busca el flujo minimo en el camino de f a s
incremento = INFINITO;//inicializa incremento a infinito
//busca el flujo residual minimo en el camino de fuente a sumidero
for(u = sumidero; padre[u] != NULO; u = padre[u]){
residual = grafo[padre[u]][u].capacidad- grafo[padre[u]][u].flujo;
incremento = min( incremento, residual);
}
//actualiza los valores de flujo, flujo maximo y residual en el camino
for(u = sumidero; padre[u] != NULO; u = padre[u]){
//actualiza los valores en el sentido de fuente a sumidero
grafo[padre[u]][u].flujo += incremento;
//hace lo contrario en el sentido de sumidero a fuente
grafo[u][padre[u]].flujo -= incremento;
}
// muestra la ruta
for (u=sumidero; padre[u]!=(-1); u=padre[u])
printf(“ %d< −”,u);
printf(“ %d añade %d de flujo adicional\n”, fuente,incremento);
flujomax += incremento;
}//al salir del ciclo ya no quedan rutas de incremento de flujo se devuelve el ciclo maximo
return flujomax;
}
int main(){
int narist;
int a, b, c;
int fuente, sumidero;
int flujo;
//leer parametros del grafo
printf(“numero de vertice y numero de aristas\n”);
scanf(“ %d %d”, &nvert, &narist);
//inicializar el grafo
inicia grafo();
//leer las aristas
printf(“ingresa la arista en el orde v1 v2 peso\n”);
while(narist){
//leer arista (a,b) con capacidad c
scanf(“ %d %d %d”, &a, &b, &c);
inserta arista(a, b, c);
narist–;
}
for(int i = 0; i < nvert; i + +)
for(int j = 0; j < nvert; j + +)
printf(“grafo[ %d][ %d] = %d\n”, i, j, grafo[i][j].capacidad);
//leer la consulta
printf(“introduce el vertice fuente y el sumidero del grafo\n”);
scanf(“ %d %d”, &fuente, &sumidero);
flujo = ford fulkerson(fuente, sumidero);
printf(
el flujo maximo entre %d y %d es %d\n”, fuente, sumidero, flujo);
printf(“El flujo entre los vertices quedo asi\n”);
for(int i = 0; i < nvert; i + +)
for(int j = 0; j < nvert; j + +)
if( (i != j) && (grafo[i][j].flujo != 0) )
printf(“( %d, %d) = %d\n”, i, j, grafo[i][j].flujo);
return 0;
}
11
aqui vemos una corrida de como deberia funcionar el algoritmo de Ford-
Fulkerson:
12
Figura 5: corrida del programa ford fulkerson.cpp.
como podemos ver el flujo maximo que nos regresa entre el vertice fuente
1(vertice s en el grafo) y el vertice sumidero 4(vertice t en el grafo) es 14.
Conclusión:
Referencias:
13