An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las...

13
An´ alisis de Algoritmos Profesor: M.C. Cuauhtemoc Gomez Suarez Tarea 06: Para calificaci´ on de examen. Secci´ on: 503 Manuel Alejandro Salazar Mej´ ıa. Matr´ ıcula: 0300704C 11 de enero de 2011 1

Transcript of An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las...

Page 1: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

Analisis de Algoritmos

Profesor: M.C. Cuauhtemoc Gomez Suarez

Tarea 06: Para calificacion de examen.

Seccion: 503

Manuel Alejandro Salazar Mejıa.

Matrıcula: 0300704C

11 de enero de 2011

1

Page 2: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

Tarea:

a) Programar la solucion para el problema de las rutas mas cortas de to-dos los pares.* Utilizar el algoritmo de Floyd-Warshall* Utilizar matrices de adyacencia para la representacion de los grafos

El algoritmo de Floyd-Warshall

Utilizaremos una formulacion diferente de programacion dinamica pararesolver el problema de todos los pares de rutas mas cortas en un grafo di-rigido G = (V,E). El algoritmo resultante, conocido como el algoritmo deFloyd-Warshall, se ejecuta en tiempo de Θ(V 3). Como antes, vertices conpesos negativos pueden estar presentes, pero asumimos que no hay ciclos conpeso negativo. El algoritmo de Floyd-Warshall considera vertices intermediosen una ruta mas corta, y se basa en la siguiente observacion. De acuerdo connuestro supuesto de que los vertices de G son V = {1, 2, ..., n} , consideremosun subconjunto {1, 2, ..., k} de vertices para algun k. Para cualquier par devertices i, j ε V , tenga en cuenta todas las rutas i a j cuyos vertices interme-dios estan formados por {1, 2, ..., k}, y sea p una ruta con el mınimo peso deentre ellos. Por lo que explota una relacion entre la ruta p y rutas mas cortasde i a j con todos los vertices intermedios en el conjunto {1, 2, ..., k− 1}. Larelacion depende de si k es un vertice intermedio de la ruta p.

- Si k no es un vertice intermedio de la ruta p, entonces todos los verticesintermedios de la ruta p estan en el conjunto {1, 2, ..., k − 1}.

- Si k es un vertice intermedio de la ruta p, entonces separamos p en ip1

kp2 j, asi vemos que p1 es una ruta mas corta de i a k con todos sus vertices

intermedios en {1, 2, ..., k − 1}. Del mismo modo, p2 es unaruta mas cortadesde el vertice k a el vertice j con todos los vertices intermedios en el con-junto {1, 2, ..., k − 1}.

Entonces encontrando una solucion recursiva para el problema de todos lospares de rutas mas cortas definimos:

d(k)ij como el peso de la ruta mas corta desde el vertice i al vertice j, para

los cuales todos los vertices intermedios estan en el conjunto {1, 2, ..., k}.

2

Page 3: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

y

d(k)ij =

{wij k = 0

min(d(k−1)ij , d

(k−1)ik + d

(k−1)kj ) k ≥ 1

ahora para saber como se altera la matriz de predecesores, podemos dar unaformulacion recursiva de Π

(k)ij . Cuando k = 0, una ruta mas corta de i hasta

j no tiene vertices intermedios en absoluto. Por lo tanto,

Π(0)ij =

{NIL if i = j or wij =∞i if i 6= j and wij <∞

Para k ≥ 1, si tomamos la ruta i k j:

Π(k)ij =

(k−1)ij if d

(k−1)ij ≤ d

(k−1)ik + d

(k−1)kj ,

Π(k−1)kj if d

(k−1)ij > d

(k−1)ik + d

(k−1)kj .

Algoritmo de Floyd-Warshall.

pseudocodigo

FLOYD-WARSHALL(W )1: n← rows[W ]2: D(0) ← W3: para k ← 1 hasta n hacer4: para i← 1 hasta n hacer5: para j ← 1 hasta n hacer

6: d(k)ij ← min(d

(k−1)ij , d

(k−1)ik + d

(k−1)kj )

7: fin para8: fin para9: fin para10: regresa D(n)

11: regresa Π(n)

3

Page 4: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

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;

//matrices de pesos y de padresint W[5][5];int Padre[5][5];//inicializar la matriz de adyacencia y de padresvoid inicializar(){

for(int i = 0; i < 5; i + +)for(int j = 0; j < 5; j + +){

Padre[i][j] = NIL;if(i == j) W[i][j] = 0;else W[i][j] = INF;

}}//insertar una arista validando i = jvoid inserta arista(int i, int j, int w){

if(i == j) W[i][j] = 0;else{

W[i][j] = w;Padre[i][j] = i+1;

}}//validacion para suma con infinitoint suma(int x, int y){

if( x == INF —— y == INF)return INF;

elsereturn x + y;

}algoritmo que calcula las rutas mas cortasvoid floyd warshall(){

//ciclo principal de floyd warshallfor(int k = 0; k < 5; k + +)

for(int i = 0; i < 5; i + +)for(int j = 0; j < 5; j + +)

if( W[i][j] > suma(W[i][k], W[k][j]) ){W[i][j] = suma(W[i][k], W[k][j]);Padre[i][j] = Padre[k][j];

}printf(“W =\n”);for(int i = 0; i < 5; i + +){

for(int j = 0; j < 5; j + +)printf(“ %d ”, W[i][j]);

printf(“\n”);}printf(“P =\n”);for(int i = 0; i < 5; i + +){

for(int j = 0; j < 5; j + +)printf(“ %d ”, Padre[i][j]);

printf(“\n”);}

}

4

Page 5: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

int main(){int narist;int a, b, c;

printf(“ingresa el numero de aristas\n”);scanf(“ %d”, &narist);//inicializar la matriz de adyacencias y la matriz de predecesoresinicializar();//leer las aristasprintf(“ingresa la arista en el orden: vertice1 vertice2 peso\n”);while(narist){

//leer arista (a,b) con capacidad cscanf(“ %d %d %d”, &a, &b, &c);inserta arista(a, b, c);narist–;

}floyd warshall();return 0;

}

dicho codigo se ha implementado para la resolucion del siguiente grafo:

Figura 1: Grafo a resolver con el algoritmo de Floyd-Warshall.

5

Page 6: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

en la figura 2 podemos ver una corrida de la forma en que trabaja el algoritmode Floyd-Warshall:

Figura 2: corrida del algoritmo de Floyd-Warshall sobre el grafo de la figura1.

6

Page 7: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

ahora ejecutando el archivo floyd warshall.cpp:

Figura 3: ejecucion del programa floyd warshall.cpp.

como se puede observar el resultado es el mismo W es la matriz resultantey P es la matriz de predecesores con la que se puede reconstruir la ruta mascorta obtenida pero eso esta fuera de mi alcance.

7

Page 8: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

b) Programar la solucion para el problema del flujo maximo* Utilizar el metodo de Ford-Fulkerson

El algoritmo de Ford-Fulkerson

Para comprender mejor este algoritmo es necesario definir algunos concep-tos. Primero decimos que un grafo que representa flujos es un grafo dirigido yponderado, donde el peso de las aristas representa una capacidad maxima detransportar un flujo. El flujo residual es el flujo disponible en una determi-nada arista una vez que se ha enviado flujo por ella (en ningun caso el flujoneto residual debe ser mayor a la capacidad de dicha arista ni menor quecero). El flujo residual lo calculamos como la capacidad menos flujo actual,donde flujo actual es el flujo que ya se ha ocupado en alguna iteracion delalgoritmo. Un camino de flujo residual es aquel camino de la fuente al sum-idero donde todas las aristas en el camino tienen un flujo residual mayor acero. El algoritmo comienza por hacer que el flujo actual en todas las aris-tas del grafo sea igual a cero, en consecuencia el flujo residual sera igual ala capacidad de las mismas. El siguiente paso es encontrar un camino de lafuente al sumidero donde todas las aristas incluidas en el camino tengan unacapacidad residual mayor a cero. La cantidad maxima de flujo que puedeenviarse al sumidero por dicho camino corresponde como es logico al valor dela capacidad residual mınima en dicho camino. A esta cantidad se le denom-ina incremento en el flujo, debido a que se suma al flujo actual en todas lasaristas en el camino encontrado. La consecuencia inmediata es que el flujoresidual se vera modificado y la arista con la menor capacidad estara trans-portando el flujo maximo (su flujo residual se convertira en cero) y por lotanto no debera ser considerada en la siguiente iteracion del algoritmo. Esteproceso se repite siempre que pueda encontrarse un nuevo camino de flujoresidual (un camino donde todas las aristas tengan un flujo residual mayora cero). Al final el flujo maximo que puede enviarse de la fuente al sumiderocorresponde a la suma de todos los incrementos calculados con cada nuevocamino encontrado. El algoritmo de Ford-Fulkerson depende fuertemente delmetodo que se use para encontrar los caminos de flujo residual y estos a suvez dependen de la forma en la que se represente el grafo. Por un lado, larepresentacion de matrices hace muy rapido el encontrar el valor de los flujosy las capacidades de cada arista pero hace lento el encontrar los nodos ady-acentes y por lo tanto la busqueda de caminos. Por otro lado, las listas deadyacencias hacen muy rapido el encontrar los nodos adyacentes pero hacenlento el encontrar el valor de los flujos y capacidades.

8

Page 9: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

En cada iteracion del metodo de Ford-Fulkerson, encontramos algunasrutas p que aumentan e incrementan el flujo f en cada vertice de p por la ca-pacidad residual cf (p). La consecuencia de la aplicacion del metodo calcula elcaudal maximo en un grafo G = (V,E), poniendo al dıa el flujo f [u, v] entrecada par u, v de vertices que estan conectados por una vertice. Si u y v noestan conectados por una arista en cualquier direccion, se supone implıcita-mente que f [u, v] = 0. La capacidad de c(u, v) se supone que se administrajunto 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] hacer2: f [u, v]← 03: f [v, u]← 04: mientras existaunarutapdeshastatenlaredresidualGf hacer5: cf (p)← min{cf (u, v) : (u, v)estaenp}6: para cadavertice(u, v)enp hacer7: f [u, v]← f [u, v] + cf (p)8: f [v, u]← −f [u, v]9: fin para10: fin mientras

9

Page 10: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

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;

//definicion de una estructura para almacenar los flujos actuales y capacidadestypedef struct{

int flujo;int capacidad;

}FLUJOS;//el grafo se almacena como una matrizFLUJOS grafo[MAXVERT][MAXVERT];int nvert, padre[MAXVERT];//valores iniciales de los flujos antes de insertar aristasvoid inicia grafo(){

for(int i = 0; i < nvert; i + +)for(int j = 0; j < nvert; j + +)

grafo[i][j].capacidad = 0;}//se considera que puede haber mas de una arista entre cada para de verticesvoid inserta arista(int origen, int destino, int capacidad){

grafo[origen][destino].capacidad += capacidad;}//busqueda de caminos residuales, devuelve verdadero al encontrar un caminoint BFS(int fuente, int sumidero){

int visitado[MAXVERT], u, v, residual;list< int > cola;//inicializar la busquedafor(u = 0;u < nvert;u + +){

padre[u] = NULO;visitado[u] = 0;

}cola.clear();//hacer la busquedavisitado[fuente] = 1;cola.push back(fuente);//ciclo principal de la busqueda por anchurawhile(!cola.empty()){

//saca nodo de la colau = cola.front(); cola.pop front();for(v = 0; v < nvert; v + +){

//elige aristas con flujo residual mayor a cero en el recorridoresidual = grafo[u][v].capacidad - grafo[u][v].flujo;if(!visitado[v] && ( residual > 0)){

cola.push back(v);//mete nodo a la colapadre[v] = u;//guarda a su padrevisitado[u] = 1;//lo marca como visitado

}}

}//devolver estado del camino al sumidero al terminar el recorridoreturn visitado[sumidero];

}//algoritmo de ford-fulkersonint ford fulkerson(int fuente, int sumidero){

int flujomax, incremento, residual, u;//los flujos a cero antes de iniciar el algoritmo

10

Page 11: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

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 residualwhile(BFS(fuente, sumidero)){

//busca el flujo minimo en el camino de f a sincremento = INFINITO;//inicializa incremento a infinito//busca el flujo residual minimo en el camino de fuente a sumiderofor(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 caminofor(u = sumidero; padre[u] != NULO; u = padre[u]){

//actualiza los valores en el sentido de fuente a sumiderografo[padre[u]][u].flujo += incremento;//hace lo contrario en el sentido de sumidero a fuentegrafo[u][padre[u]].flujo -= incremento;

}// muestra la rutafor (u=sumidero; padre[u]!=(-1); u=padre[u])

printf(“ %d< −”,u);printf(“ %d anade %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 maximoreturn flujomax;

}int main(){

int narist;int a, b, c;int fuente, sumidero;int flujo;//leer parametros del grafoprintf(“numero de vertice y numero de aristas\n”);scanf(“ %d %d”, &nvert, &narist);//inicializar el grafoinicia grafo();//leer las aristasprintf(“ingresa la arista en el orde v1 v2 peso\n”);while(narist){

//leer arista (a,b) con capacidad cscanf(“ %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 consultaprintf(“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

Page 12: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

aqui vemos una corrida de como deberia funcionar el algoritmo de Ford-Fulkerson:

Figura 4: corrida del algoritmo Ford-Fulkerson.

como se puede apreciar el resultado del flujo maximo obtenido es en el incisod) con un valor de 14.

ahora haciendo la corrida del programa ford fulkenson.cpp se tiene:

12

Page 13: An alisis de Algoritmos · PDF fileTarea: a) Programar la soluci on para el problema de las rutas m as cortas de to-dos los pares. * Utilizar el algoritmo de Floyd-Warshall * Utilizar

Figura 5: corrida del programa ford fulkerson.cpp.

como podemos ver el flujo maximo que nos regresa entre el vertice fuente1(vertice s en el grafo) y el vertice sumidero 4(vertice t en el grafo) es 14.

Conclusion:

Como podemos ver el algoritmo de floyd-warshall efectivamente regresa laruta mas corta de un grafo. Y en cambio el algoritmo de ford-fulkerson nosregresa el flujo maximo que se puede transportar desde un origen o fuentehasta un consumidor o sumidero, los dos creo que tienen muchas aplicacionesque ya se han mencionado en clase, recuerdo que el de floyd se puede utilizaren planeacion de vuelos y cosas por el estilo, y el de ford en cambio se puedeutilizar para determinar si se cumplen las leyes de Kirchoff donde la sumade los flujos entrantes a un vertice, debe de ser igual a la suma de los flujossaliendo del vertice.

Referencias:

* Thomas H. Cormen, Charles E. Leiserson, Introduction to Algorithms,Second Edition

13