Advertisement
Gustavo_Inzunza

Ant Colony

Jul 5th, 2013
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.81 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cmath>
  4. #include <vector>
  5. #include <stdio.h>
  6. #include <string>
  7. using namespace std;
  8. typedef struct
  9. {
  10.     long double peso,feromona;
  11. }Dato;
  12. int nodo_i,nodo_j;//N es la cantidad de nodos/vertices del grafo
  13. long double feromona_init;
  14. vector< int > recorrido(52),temporal(52);
  15. vector< vector< int > > hormigas(10),opciones(10);//las hormigas poseen la ruta recorrida
  16. vector< vector< Dato > > ciudad(52);
  17. long double feromona_inicial()
  18. {
  19.     vector<int> caminos_disponibles=temporal,elegido;
  20.     random_shuffle(caminos_disponibles.begin(),caminos_disponibles.end());
  21.     elegido.push_back(caminos_disponibles[0]);
  22.     caminos_disponibles.erase(caminos_disponibles.begin());
  23.     long double distancia_inicial=0;
  24.     int posicion;
  25.     while(!caminos_disponibles.empty())
  26.     {
  27.         long double peso_menor=100000;
  28.         for (int j = 0; j < caminos_disponibles.size(); ++j)
  29.             if (ciudad[elegido.back()][caminos_disponibles[j]].peso<peso_menor)
  30.             {
  31.                 peso_menor=ciudad[elegido.back()][caminos_disponibles[j]].peso;
  32.                 posicion=j;
  33.             }
  34.         distancia_inicial+=ciudad[elegido.back()][caminos_disponibles[posicion]].peso;
  35.         elegido.push_back(caminos_disponibles[posicion]);
  36.         caminos_disponibles.erase(caminos_disponibles.begin()+posicion);
  37.     }
  38.     distancia_inicial+=ciudad[elegido[0]][elegido.back()].peso;
  39.     return distancia_inicial;
  40. }
  41. void asignar_hormigas()
  42. {
  43.     random_shuffle(temporal.begin(),temporal.end());
  44.     for (int i = 0; i < 10; ++i)
  45.     {
  46.         hormigas[i][0]=temporal[i];//todas las hormigas tendran asignado un nodo distinto al principio
  47.         opciones[i].erase(opciones[i].begin()+temporal[i]);//elimino la opción elegida para que no se repita más adelante
  48.     }
  49. }
  50. long double ecuacion1_y_2(int i,int pos_anterior,int numero_nodo)//i es numero de hormiga y pos anterior es el nodo en que esta parada
  51. {//numero nodo es cual numero de nodo estamos eligiendo para caminar sobre él
  52.     int posicion,coeficiente;
  53.     if((rand()%100)<=90)
  54.     {
  55.         posicion=opciones[i][0],coeficiente=0;
  56.         long double max=(ciudad[pos_anterior][opciones[i][0]].feromona)*pow(1/(ciudad[pos_anterior][opciones[i][0]].peso),2.5);
  57.         for (int j = 1; j < opciones[i].size(); ++j)
  58.         {
  59.             long double valor=(ciudad[pos_anterior][opciones[i][j]].feromona)*pow(1/(ciudad[pos_anterior][opciones[i][j]].peso),2.5);
  60.             if(valor>max)
  61.             {
  62.                 max=valor;
  63.                 posicion=opciones[i][j];
  64.                 coeficiente=j;
  65.             }
  66.         }
  67.     }
  68.     else//ecuacion 2
  69.     {
  70.         long double sumatoria=0;
  71.         vector< pair<int,int> > porciones_ruleta;
  72.         posicion=opciones[i][0],coeficiente=0;//asumo el primer recorrido disponible como el primer candidato
  73.         for (int j = 0; j < opciones[i].size(); ++j)//aca se calcula sumatoria de ecuacion 2
  74.             sumatoria+=(ciudad[pos_anterior][opciones[i][j]].feromona)*pow(1/(ciudad[pos_anterior][opciones[i][j]].peso),2.5);
  75.         for (int j = 0; j < opciones[i].size(); ++j)
  76.         {
  77.             long double valor=(ciudad[pos_anterior][opciones[i][j]].feromona)*pow(1/(ciudad[pos_anterior][opciones[i][j]].peso),2.5);
  78.             valor/=sumatoria;valor*=100;
  79.             porciones_ruleta.push_back(make_pair(valor,j));
  80.         }
  81.         sort(porciones_ruleta.begin(), porciones_ruleta.end());
  82.         int ruleta=rand()%100;
  83.         for (int inicio = 0; inicio < porciones_ruleta.size(); ++inicio)
  84.         {
  85.             if(ruleta<=porciones_ruleta[inicio].first)
  86.                 coeficiente=porciones_ruleta[inicio].second;
  87.         }
  88.         posicion=opciones[i][coeficiente];
  89.        
  90.     }
  91.     hormigas[i][numero_nodo]=posicion;
  92.     ciudad[pos_anterior][posicion].feromona=0.9*(ciudad[pos_anterior][posicion].feromona)+0.1*feromona_init; //actualizacion local de feromona
  93.     ciudad[posicion][pos_anterior].feromona=ciudad[pos_anterior][posicion].feromona;//actualizacion local de feromona
  94.     opciones[i].erase(opciones[i].begin()+coeficiente);//elimino el nodo elegido por la hormiga para que no se repita
  95.     //cout<<"hormiga "<<i<<" camino:"<<posicion<<endl;
  96.     return (ciudad[pos_anterior][posicion].peso);
  97. }
  98. int main()
  99. {
  100.     long double peso,peso_menor=100000;
  101.     srand(time(NULL));
  102.     for (int i = 0; i < 52; ++i)
  103.     {
  104.         temporal[i]=i;
  105.         if(i<10)
  106.         {
  107.             opciones[i].resize(52);
  108.             hormigas[i].resize(52);
  109.         }
  110.         ciudad[i].resize(52);
  111.         for (int j = 0; j < 52; ++j)
  112.             if(i<10)
  113.                 opciones[i][j]=j;
  114.     }
  115.     while(scanf("%d %d %Lf",&nodo_i,&nodo_j,&peso)!=EOF)
  116.     {
  117.         ciudad[nodo_i-1][nodo_j-1].peso=peso;
  118.         ciudad[nodo_j-1][nodo_i-1].peso=peso;
  119.     }
  120.     feromona_init=1/feromona_inicial();
  121.     for (int i = 0; i < 52; ++i)
  122.         for (int j = i+1; j < 52; ++j)
  123.         {
  124.             ciudad[i][j].feromona=feromona_init;
  125.             ciudad[j][i].feromona=feromona_init;
  126.         }
  127.     short int iteracion=0;
  128.     while(iteracion++!=100)
  129.     {
  130.         asignar_hormigas();
  131.         for (int i = 0; i < 10; ++i)//para cada hormiga
  132.         {
  133.             long double distancia=0,feromona_total=0;
  134.             for (int j = 1; j <52; ++j)//considerando que ya tiene un nodo de partida
  135.                 distancia+=ecuacion1_y_2(i,hormigas[i][j-1],j);//criterio de seleccion de camino
  136.             distancia+=ciudad[hormigas[i][0]][hormigas[i][51]].peso;//le agrego distancia del inicio al fin
  137.             ciudad[hormigas[i][0]][hormigas[i][51]].feromona=0.9*(ciudad[hormigas[i][0]][hormigas[i][51]].feromona)+0.1*feromona_init;
  138.             ciudad[hormigas[i][51]][hormigas[i][0]].feromona=0.9*(ciudad[hormigas[i][51]][hormigas[i][0]].feromona)+0.1*feromona_init;
  139.             if(distancia<peso_menor)
  140.             {
  141.                 peso_menor=distancia;
  142.                 recorrido=hormigas[i];
  143.                 for (int inicio = 1; inicio < 52; ++inicio)//aumento feromona global al camino recorrido por la hormiga
  144.                 {
  145.                     ciudad[hormigas[i][inicio-1]][hormigas[i][inicio]].feromona=0.9*ciudad[hormigas[i][inicio-1]][hormigas[i][inicio]].feromona+0.1*(1/peso_menor);
  146.                     ciudad[hormigas[i][inicio]][hormigas[i][inicio-1]].feromona=ciudad[hormigas[i][inicio-1]][hormigas[i][inicio]].feromona;
  147.                 }
  148.                 ciudad[hormigas[i][0]][hormigas[i][51]].feromona=0.9*ciudad[hormigas[i][0]][hormigas[i][51]].feromona+0.1*(1/peso_menor);
  149.                 ciudad[hormigas[i][51]][hormigas[i][0]].feromona=ciudad[hormigas[i][0]][hormigas[i][51]].feromona;
  150.                 for (int inicio = 0; inicio < 52; ++inicio)//aca se evapora la feromona de los caminos no elegidos
  151.                     for (int j = inicio+1; j < 52; ++j)
  152.                     {
  153.                         int flag=0;
  154.                         for(int k=1;k<hormigas[i].size();k++)
  155.                             if((inicio==hormigas[i][k] and j==hormigas[i][k-1])or(inicio==hormigas[i][k-1] and j==hormigas[i][k]))
  156.                             {//verifica que no sea un camino elegido por la hormiga el que se va a evaporar
  157.                                 flag=1;
  158.                                 break;
  159.                             }
  160.                         if(!flag)//si no fue uno elegido por la hormiga entonces lo evapora
  161.                         {
  162.                             ciudad[inicio][j].feromona=0.9*ciudad[inicio][j].feromona;
  163.                             ciudad[j][inicio].feromona=0.9*ciudad[j][inicio].feromona;
  164.                         }
  165.                     }
  166.             }
  167.             opciones[i].clear();
  168.             opciones[i].resize(52);
  169.         }
  170.         for (int i = 0; i < 10; ++i)//se vuelven a crear los valores validos de opciones para las hormigas
  171.             for (int j = 0; j < 52; ++j)
  172.                 opciones[i][j]=j;
  173.     }
  174.     cout<<"La distancia menor es:"<<peso_menor<<endl;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement