Algoritmo de Optimización Por Colonia de Hormigas
Algoritmo de Optimización Por Colonia de Hormigas
Algoritmo de Optimización Por Colonia de Hormigas
(ACO)
INTRODUCCIÓN
El problema del viajero tiene numerosas aplicaciones en las que resaltan el recorrido
de un transporte escolar, paquetería y correo, Agencia de viajes (Tours) entre otras.
La dificultad de éste problema es que conforme aumenten el nú mero de nodos,
aumentará n las rutas y por lo tanto las combinaciones se incrementarían.
É ste problema puede resolverse con ACO, pero ¿qué es ACO? Por sus siglas en inglés
Ant Colony Optimization (Optimizació n Colonia de Hormigas), se le llama así porque
simula el comportamiento de las hormigas desde su hormiguero a la fuente de comida.
Mientras se mueven entre estos dos puntos van dejando un rastro de feromona que
ayuda a determinar un camino ó ptimo que las demá s hormigas puedan seguir.
La relació n de ACO con el problema del viajero es que ésta técnica utiliza la
probabilidad para resolver problemas donde su solució n sea el mejor camino o ruta
en un grafo siendo este el objetivo del problema del viajero.
MARCO TEÓRICO
El problema consiste en un viajante que tienen un nú mero de destinos los cuales debe
visitar, puede partir de cualquier punto con la condició n de regresar al mismo. Los
demá s destinos solo pueden ser visitados una vez por recorrido. El objetivo es
recorrer los lugares cuidando que la ruta sea la de menor costo.
Se representa con la estructura de grafo debido a que sus nodos simbolizan ciudades y
las ramas los caminos que puede recorrer siendo la conexió n de los lugares. Se
considera un problema NP-completo ya que es un algoritmo no eficiente, pero existe
la validació n para la supuesta solució n
A continuació n se mostrará una instancia resuelta por fuerza bruta donde se verá con
mayor claridad la estructura de grafo del problema.
Realizamos un ejemplo para poder resolverlo por fuerza bruta; es decir crear todas las
combinaciones posibles para que del estado inicial se recorran todos los nodos a
través de las aristas regresando al lugar de inicio sin pasar 2 veces o má s por un
mismo nodo.
El objetivo es identificar por este método cuá l es el camino ó ptimo para realizar el
recorrido.
Instancia: Un niñ o tiene que hacer un recorrido que su madre le ordenó , no importa
donde empiece solo tiene que terminar en el mismo sitio con la restricció n ya
especificada anteriormente. Consiste en pasar por cada uno de los lugares e intentar
hacerlo en el menor tiempo posible, los nú meros que se encuentran en la imagen son
la cantidad de calles que el niñ o tiene que atravesar para ir de un lugar a otro, también
se muestran los 5 lugares a los que tiene que ir. La solució n trata en encontrar el
recorrido por donde el niñ o cruce menos calles para disminuir el tiempo del traslado.
Solución:
Como vamos a estar trabajando con varias combinaciones será un poco tedioso estar
viendo todo el nombre del lugar por lo que decidimos poner solo una letra que
identifique a cada uno de ellos.
Tienda=A
Florería=B
Tortillería=C
Carnicería=D
Panadería=E
Como una de las restricciones es que el recorrido comienza en el mismo lugar donde
finaliza, eso nos permite eliminar unas cuantas combinaciones esto porque coinciden
con otras al momento de leerlas inversamente, por lo que al momento de hacer la
suma de las calles que se pasan en cada recorrido nos dará n el mismo resultado.
Después de utilizar el método de fuerza Bruta para hacer los recorridos por los 5
lugares pudimos identificar los caminos ó ptimos que el niñ o puede tomar para
cumplir el objetivo de ir a los 5 lugares recorriendo el camino con menos calles.
SELECCIÓ N DE CAMINO
La Actualización de Feromona se da cuando se deposita la feromona y luego se evapora, así
para cada hormiga
Marco Teó rico donde se muestra informació n general sobre ACO para entender y
tener una mejor idea del algoritmo ademá s de datos sobre su origen y relació n con el
comportamiento de Hormigas.
En la secció n de Desarrollo se mostrará el funcionamiento a partir de las fó rmulas,
empezando por explicar có mo funciona el algoritmo relacionado con el problema del
viajero para después presentar la codificació n de ACO mostrando su comportamiento.
Se mostrará n ademá s, en esta secció n, los pará metros que utilizamos por ejemplo, la
cantidad de hormigas, la tasa de evaporació n, el valor inicial de la feromona , etc.
Para aclarar puntos sobre el problema del viajero se han creado dos instancias, una de
pocas ciudades y otra de 10 ciudades para mostrar el representar del problema del
viajero de forma grá fica y por medio de un generador de instancias.
DESARROLLO
Algoritmo
Inicializació n del algoritmo.
void Dibujar_instancia(int Distancias,double Costos)
{
system("cls");
srand(time(NULL));
//Distancias
cout<<"\nDISTANCIAS:\n";
for(i=0;i&alt;Nodos;i++)
{
for(j=i;j<(Nodos);j++)
{
if(j==i)
{
Distancias[i][j]=0;
}else
{
num=1+rand()%(21-1);
Distancias[i][j]=num;
Distancias[j][i]=num;
}
}
for(j=0;j<Nodos;j++)
{
cout<<setw(4)<<Distancias[i][j];
}
cout<<"\n";
}
//Costos
cout<<"\n\nCOSTOS\n";
for(i=0;i<Nodos;i++)
{
for(j=0;j<Nodos;j++)
{
if(i==j)
{
Costos[i][j]=0;
}else
{
Costos[i][j]=(1/(float)Distancias[i][j]);
}
cout<<" "<<setw(6)<<setprecision(3)<<Costos[i][j];
}
cout<<"\n";
}
//Feromonas
cout<<"\n\nFEROMONAS:\n";
for(i=0;i<Nodos;i++)
{
for(j=i;j<Nodos;j++)
{
if(j==i)
{
Feromonas[i][j]=0;
}else
{
num=1+rand()%(100-1);
numf=(float)num/100;
Feromonas[i][j]=numf;
Feromonas[j][i]=numf;
}
}
for(j=0;j<Nodos;j++)
{
cout<<" "<<setw(5)<<setprecision(5)<<Feromonas[i][j];
}
cout<<"\n";
}
return;
}
int main()
{
cout<<"Numero de nodos: ";
cin>>Nodos;
int Distancias[Nodos][Nodos];
float Feromonas[Nodos][Nodos];
double Costos[Nodos][Nodos];
int Recorridas[Nodos][Nodos], Proximas[Nodos][Nodos];
Dibujar_instancia(Distancias,Costos);
for(I=1;I<=5;I++)//5 veces
{
Elegir_CiudadInicio(Recorridas);
for(H=1;H<=3;H++)//para cada hormiga
{
Seleccion_deCamino(Feromonas,Costos,Proximas,Recorridas);
Moverse();
Sumar_Costo();
}
DepositarFeromonas(Feromonas);
ImprimirMejorCamino();
}
ImprimirResultados();
system("PAUSE");
}
i=0;
for(q=0;q<Nodos;q++)
{
si_esta=0;
if(Recorridas[toper]=q)
{
si_esta=1;
}else
{
for(l=0;l<=toper;l++)
{
if(q=Recorridas[l])
{
si_esta=1;
}
}
}
if(si_esta=0)
{
Proximas[i]=q;
topep=i;
i++;
}
}
//Probabilidades y cachos
double arriba,abajo;
for(i=0;i<=topep;i++)
{
arriba=0;
abajo=0;
arriba=(pow((Feromonas[(Recorridas[toper])]
[(Proximas[i])]),1)*pow((Costos[(Recorridas[toper])][(Proximas[i])]),1));
for(l=0;l<=topep;l++)//sumatoria de abajo ;)
{
abajo=abajo+((Feromonas[(Recorridas[toper])]
[(Proximas[l])])*(Costos[(Recorridas[toper])][(Proximas[l])]));
}
Probabilidad[i]=(arriba/abajo);
}
i=0;l=0;
while(i<=100)
{
for(ii=0;ii<=(Probabilidad[l]*100);ii++)
{
Ruleta[i]=Proximas[l];
i++;
}
l++;
}
num=0+rand()%(99-0);
//agregar a cds recorridas
hacia=Ruleta[num];
Recorridas[toper][1]=hacia;
toper++;
desde=hacia;
Recorridas[toper][0]=desde;
}
return;
}
Actualizació n de la feromona
void DepositarFeromonas(float Feromonas[Nodos][Nodos])
{
float nuevafer,sumatoriaLK;
for(i=0;i<toper;i++)
{
sumatoriaLK+=Feromonas[(Recorridas[i])][(Recorridas[1])]
}
sumatoriaLK+=(1/Nodos);
for(i=0;i<Nodos;i++)
{
for(j=i;j<Nodos;j++)
{
if(j==i)
{
Feromonas[i][j]=0;
}else
{
nuevafer=((1-0.5)*Feromonas[i][j])+ssumatoriaLK;
Feromonas[i][j]=nuevafer;
Feromonas[j][i]=nuevafer;
}
}
}
return;
}
INSTANCIA 1
INSTANCIA 2
A partir del ejecutable anterior (instancia 2) podremos acomodar los datos en una
matriz que nos quedaría así
Este mapa de destinos corresponde a la instancia 2
CONCLUSIÓN
En conclusión de ACO…
El algoritmo ACO aunque de principio parecía fácil, ya que el concepto que utiliza es muy
sencillo de entender, al programarlo no resulto de esa forma, incluso nos causó muchas
confusiones, mismas que se fueron solucionando al ir desenvolviendo el problema y
dividiéndolo parte por parte. Por lo que este algoritmo a pesar de tener muchos pasos a
seguir, puede ser programado y reutilizado para más problemas no solo con el problema del
viajero.
Pero también entendemos que es mucho mejor opción utilizar este algoritmos para resolver
el problema del viajero, a resolverlo por fuerza bruta, ya que con instancias muy grandes
podríamos tardar realmente demasiado tiempo en resolver.