Sei sulla pagina 1di 13

Problema: De un conjunto de N ciudades y sus conexiones con costos, se quiere encontrar la ruta ms efectiva de manera que se recorran todas

las ciudades partiendo de una ciudad K dada.

Restricciones: * Slo se puede pasar una vez por cada ciudad en el recorrido. * No existen islas (nodos aislados). * Las aristas son no dirigidas (se puede utilizar en ambos sentidos). * Existe al menos un camino hamiltoniano partiendo del punto dado.

Solucin 1: Algoritmo Voraz. El algoritmo consiste en siempre tomar el ptimo local y proceder desde ah. La acumulacin secuencial de estos ptimos locales nos arrojan la respuesta. Cabe recalcar que dado que no se exploran el resto de las opciones es muy posible que el ptimo global encontrado no sea el mejor.

Ej. Para el siguiente grafo, magistralmente dibujado:

Se quiere encontrar la mejor ruta partiendo de la ciudad "1". Primeramente, se requiere convertir dicha informacin a un formato entendible para el programa, se ha elegido lo siguiente: Un nmero N, denotando la cantidad de nodos en el grafo; un nmero K, la ciudad de partida; un nmero M, denotando la cantidad de aristas en el grafo y a continuacin M lneas en la forma A B C, dnde A B C es el coste C que existe en viajar de la ciudad A a la B (o viceversa). 4 1 6 127 139 148 236 245 344 // N //K // M // El camino de 1 a 2 cuesta 7 //El camino de 1 a 3 cuesta 9 //El camino de 1 a 4 cuesta 8 //El camino de 2 a 3 cuesta 6 //El camino de 2 a 4 cuesta 5 //El camino de 3 a 4 cuesta 4

A continuacin el algoritmo codificado en C


#include<stdio.h> #include<stdlib.h> int i,c,n,n2,m,k,a,b,pos,costo,min,costos[100][100]; bool v[100]; int main() { //freopen("entrada.txt", "r", stdin); //freopen("optimo.txt", "w", stdout); printf("Programa que calcula la ruta ms corta/barata por algoritmo voraz para un grafo con camino hamiltoniano, partiendo de un punto dado.\n"); printf("Introduzca la cantidad de vrtices "); scanf("%d",&n); printf("Introduce el punto de partida "); scanf("%d",&k); printf("Introduzca la cantidad de aristas "); scanf("%d",&m); for(i=0;i<n;i++) { for(c=0;c<n;c++) costos[i][c]=-1; v[i]=false; } printf("A continuacin introduzca las aristas en el formato: A B C, donde A y B son el nmero de los vrtices y C el costo entre ellos\n"); for(i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&c); a--; b--; if(costos[a][b]==-1||costos[a][b]>c) costos[a][b]=costos[b][a]=c; } k--; v[k]=true; n2=n-1; costo=0; while(n2) { min=-1; for(i=0;i<n;i++) if(!v[i]&&(min==-1||(costos[k][i]<min&&costos[k][i]!=-1))) { min=costos[k][i]; pos=i; } costo+=min; v[pos]=true; k=pos; n2--;

} printf("El costo de la ruta ms corta, por algoritmo voraz, es %d\n",costo); system("pause"); return 0; }

En un principio se realiza la toma de datos(remover los comentarios de las lineas "freopen" para trabajar con archivos de texto) y la inicializacin de los valores. El cuerpo del algoritmo reside en el ciclo while(n2), aqu se busca entre las conexiones del nodo actual todos aqullos que no han sido incorporados a la ruta an. Entre ellos se elige el de menor valor (ptimo local), se incorpora a la ruta y se procede desde ese punto. Llegado el punto en que tenemos exactamente n ciudades en nuestra ruta, hemos finalizado y se reporta el ptimo encontrado. Para el ejemplo: Entrada: 4 1 6 127 139 148 236 245 344 Salida: 16

Ejemplo 2: Con el mismo algoritmo, ahora otro grafo:

Entrada: 5 1 10 1 2 100 1 3 125 1 4 100 1 5 75 2 3 50 2 4 75 2 5 50 3 4 100 3 5 125 4 5 60 Salida: 275

Solucin 2: Bsqueda con acotamiento y poda. Este algoritmo se basa en la premisa de buscar el ptimo en todo el rbol de bsqueda, por tanto su solucin es siempre exacta sin embargo, el rbol de bsqueda crece rpidamente. Para una entrada con N ciudades, el rbol de bsqueda compende (N-1)!/2 elementos, tan solo para N=10 se tiene un rbol de bsqueda de 1814400 elementos. Para aminorar este impacto podemos utilizar "acotamiento y poda", el mtodo consiste en eliminar ramas en las que sea evidente que no puede residir el ptimo global. Cabe recalcar que no se utilizan criterios heursticos por lo que no se trata de una aproximacin, slo se elimina una rama cuando se puede estar totalmente seguro que en ella no reside la solucin. En el mejor de los casos, este mtodo puede reducir drsticamente el espacio de bsqueda, aunque en el peor de los casos no se reduce en absoluto. Utilizando las mismas restricciones, formatos y entradas anteriores tenemos: #include<stdio.h> #include<stdlib.h> int i,c,n,n2,m,k,a,b,pos,costo,min,camino[100],caminopt[100],costos[100][100]; bool v[100],ady[100][100]; void ruta() { for(i=0; i<n; i++) caminopt[i]=camino[i]; } void busca(int gasto, int nodo, int n2) { camino[n2-1]=nodo; if(costo!=-1&&gasto>=costo) return; if(n2==n) { costo=gasto; ruta(); return; } for(int i=0; i<n; i++) { if(ady[nodo][i]&&!v[i]) { v[i]=true;

busca((costos[nodo][i]+gasto),i,(n2+1)); v[i]=false; } } } int main() { //freopen("entrada.txt", "r", stdin); //freopen("optimo.txt", "w", stdout); printf("Programa que calcula la ruta mas corta/barata por busqueda con acotamiento y poda para un grafo con camino hamiltoniano, partiendo de un punto dado.\n"); printf("Introduzca la cantidad de vertices "); scanf("%d",&n); printf("Introduce el punto de partida "); scanf("%d",&k); printf("Introduzca la cantidad de aristas "); scanf("%d",&m); for(i=0;i<n;i++) { for(c=0;c<n;c++) { costos[i][c]=-1; ady[i][c]=false; } v[i]=false; } printf("A continuacion introduzca las aristas en el formato: A B C, donde A y B son el numero de los vertices y C el costo entre ellos\n"); for(i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&c); a--; b--; if(costos[a][b]==-1||costos[a][b]>c) costos[a][b]=costos[b][a]=c; ady[a][b]=ady[b][a]=true; } k--; v[k]=true; costo=-1; busca(0,k,1); printf("El costo de la ruta mas corta es %d\nLa ruta es: ",costo); for(i=0;i<n;i++) printf("->%d",caminopt[i]+1);

system("pause"); return 0; } Ejemplo 1: Entrada 4 1 6 127 139 148 236 245 344 Salida El costo de la ruta ms corta es 16 La ruta es: ->1->2->4->3 Aqu se aprecia que para el ejemplo 1 se obtiene el mismo resultado. Ejemplo 2: Entrada 5 1 10 1 2 100 1 3 125 1 4 100 1 5 75 2 3 50 2 4 75 2 5 50 3 4 100 3 5 125 4 5 60 Salida El costo de la ruta mas corta es 260 La ruta es: ->1->4->5->2->3

En este caso s difiere, demostrando entonces que el algoritmo voraz no es 100% efectivo.

Como ya se mencion este algoritmo realiza una bsqueda sobre todas las posibles ramas. La poda comienza luego de que se haya encontrado la primer ruta vlida, en cuyo punto se toma el valor del recorrido encontrado como cota mxima, si en la bsqueda una rama iguala o excede la cota, la rama se poda y se continua por otro lado.

Conclusiones: Las soluciones exactas para problemas NP son muy difciles de manejar incluso para valores de N relativamente bajos. Como vimos, en la bsqueda exhaustiva el tiempo de ejecucin se dispara. Otra solucin exacta, dada por programacin dinmica(subptimos) tiene un tiempo de ejecucin rpido pero sufre a cambio en memoria, para una N=10 necesitara alrededor de 4GB de memoria para almacenar todos las posibles opciones. Por otro lado observamos que los mtodos de aproximacin pueden obtener una solucin relativamente buena en un tiempo y memoria bajos.

Tarea Resolver el problema de minimizacin de la funcin de prueba de Michalewicz para i=2. Graficar los resultados para m={1,5,10}

example=function(m) { x <- seq(0, pi, len=30) y=x z=function(x,y){-sin(x)*(sin(x^2/pi))^(2*m)-sin(y)*(sin(2*y^2/pi))^(2*m)} z <- outer(x, y, z) persp(x,y,z) } La funcin acepta un nmero m, posteriormente utilizado en la frmula. Se le asigna un rango de valores a X e Y, se calcula la funcin en Z y se grafica.

Consola:

source("a.R") example(1)

De 0 a pi

De -pi a pi

example(5)

de 0 a pi

de -pi a pi

example(10)

de 0 a pi

de -pi a pi

Potrebbero piacerti anche