ACO

来源:互联网 发布:网络远程教育报考 编辑:程序博客网 时间:2024/04/30 18:13

#include <stdio.h>#include <cmath>#include <iostream>#include <fstream>#include <time.h>using namespace std;const int iAntCount=34;//蚂蚁数量const int iCityCount=51;//城市数量const int iItCount=2000;//最大跌代次数const double Q=100;const double alpha=0;const double beta=5;const double rou=0.5;int besttour[iCityCount];//最短路径列表double  rnd(int low,double uper){ //获得随机数    double p=(rand()/(double)RAND_MAX)*((uper)-(low))+(low);    return (p);};int rnd(int uper) {    return (rand()%uper);};class GInfo { //tsp地图信息,包含了信息素,城市距离,和信息素变化矩阵public:    double m_dDeltTrial[iCityCount][iCityCount];    double m_dTrial[iCityCount][iCityCount];    double distance[iCityCount][iCityCount];};GInfo Map;class ant {private:    int ChooseNextCity();//选择城市    double prob[iCityCount]; // probability of choosing next city for each ant     int m_iCityCount; // recode the # of city in tabu     int AllowedCity[iCityCount];// city haven' been visited yet; allowed if arr[i]=1, not allow if arr[i]=0public:    int tabu[iCityCount]; // index from 0 to m_iCityCount; value == city having been visited    double m_dLength;    ant();    void addcity(int city);    void Clear();    void CalcDistance(); // ## it's better to be name as CalcLengthTour()    void move();    void move2last();};void ant::move2last() { // TODO: WHAT IS THIS FOR?     int i;    for(i=0;i<iCityCount;i++)        if (AllowedCity[i]==1) {            addcity(i);            break;        }} // ##: N ITERATION, CYCLE, EACH ANT COMPLETES A TOUR, TRAIL INTENSITY SHOULD BE UPDATED void ant::Clear() {    for(int p = 0; p < iCityCount; ++p) {        for(int q = 0; q < iCityCount; ++q) {           Map.m_dDeltTrial[p][q] = 0;        }    } // set m_dDeltTrail[i][j] = 0 for next generation     for(int p = 0; p < iCityCount; ++p)         AllowedCity[p] = 1; // set all cities to be allowed for now     m_iCityCount = 0; //clear tabu list for next iteration; m_iCityCount should be executed before addcity(i); //it matters a lot for the performance of this progm    int i = tabu[iCityCount-1]; // THIS IS DEFAULT    prob[i] = 0;    addcity(i); // AllowedCity[i] = 0; is within addcity(i)     m_dLength = 0; // set m_dLength to be 0 for next generation }ant::ant() {    m_dLength = 0;    m_iCityCount = 0;    int i;    for(i=0;i<iCityCount;i++) {        AllowedCity[i]=1;        prob[i]=0;    }}void ant::addcity(int city) {    //add city to tabu;    tabu[m_iCityCount]=city;    m_iCityCount++;    AllowedCity[city]=0;}int ant::ChooseNextCity() {    //Update the probability of path selection    //select a path from tabu[m_iCityCount-1] to next    int i;    int j=10000;    double temp = 0; // store: denominator     int curCity=tabu[m_iCityCount-1];    for (i=0;i<iCityCount;i++) {        if(AllowedCity[i]==1) {            temp+=pow((1.0/Map.distance[curCity][i]),beta) * pow((Map.m_dTrial[curCity][i]),alpha);        } // fenmu -- denominator    }    double sel=0; // TODO: what is this for?      for (i=0;i<iCityCount;i++) {        if(AllowedCity[i]==1) {            //prob[i] = pow((1.0/Map.distance[curCity][i]),(int)beta) * pow((Map.m_dTrial[curCity][i]),(int)alpha)/temp;            prob[i] =  (pow((1.0/Map.distance[curCity][i]),beta) * pow((Map.m_dTrial[curCity][i]), alpha))/temp;            sel+=prob[i]; // TODO: what is this for? // sel may stand for selection         }        else            prob[i]=0;    } // at this point sel should be almost equal to 1;         /* // Customized Probability code is MUCH less effecient     temp = prob[0];    int mmsel = 0;    for(int k = 1; k < iCityCount; ++k)        if(temp < prob[k]) {            temp = prob[k];            mmsel = k;        }    return mmsel;          */    // TODO: DEL    double mRate=rnd(0,sel); //TODO: what is this for?      double mSelect=0; // TODO: what is this for?     for ( i = 0; i < iCityCount; i++ ) {// TODO: what is this for?        if(AllowedCity[i]==1)            mSelect+=prob[i] ;        if (mSelect>=mRate) { j=i; break; }    }  // ##: IT IS PROBABLY FOR AVOID STAGNATION, PASS FOR THE MOMENT     if (j==10000) { // TODO: what is this for?         temp = -1;        for (i = 0; i < iCityCount; ++i) {            if(prob[i] > temp) {                j = i;                temp = prob[i];             }        }        // DEFAULT CODE        temp=-1;        for (i=0;i<iCityCount;i++) {            if(AllowedCity[i]==1)                if (temp)   {                    temp=pow((1.0/Map.distance[curCity][i]),beta)*pow((double)(Map.m_dTrial[curCity][i]),alpha);                    j=i;                }        }    }    return j; // just return max(prob[i]); }void ant::CalcDistance() {     // Update the length of tour of each ant     int i;    for(i=0;i<iCityCount-1;i++)        m_dLength+=Map.distance[tabu[i]][tabu[i+1]];    m_dLength+=Map.distance[tabu[iCityCount-1]][tabu[0]];}void ant::move() {    //the ant move to next town and add town ID to tabu.    int j;    j=ChooseNextCity();    addcity(j);}class project {public:    double m_dLengthVar;      ant ants[iAntCount];    project();    void UpdateTrial();    void initmap();    void GetAnt();    void StartSearch();};void project::initmap() {    int i;    int j;    for(i=0;i<iCityCount;i++)        for (j=0;j<iCityCount;j++) {            Map.m_dTrial[i][j]=1; // assign trail for each edge with a small value             Map.m_dDeltTrial[i][j]=0; // increment of trail is 0 at the beginning         }}project::project() {    //initial map,read map infomation from file . et.    initmap();    m_dLengthVar = 10e9; //TODO: what is this variable for?     ifstream in("eil51.tsp");    struct city {        int num; // # of the city        int x; // x-coordinate         int  y; // y-coordinate     }cc[iCityCount];    for (int i=0;i<iCityCount;i++) {        in>>cc[i].num>>cc[i].x>>cc[i].y;        besttour[i]=0;    } // read file     int j;    for(int i=0;i<iCityCount;i++)        for (j=0;j<iCityCount;j++) {            Map.distance[i][j]=sqrt(pow((double)(cc[i].x-cc[j].x),2)+pow((double)(cc[i].y-cc[j].y),2));        } // compute distance of every two city; TODO: can be optimized}void project::UpdateTrial() {    //calculate the changes of trial information    int i;    int j;    for(i=0;i<iAntCount;i++) {        for (j=0;j<iCityCount-1;j++) {            Map.m_dDeltTrial[ants[i].tabu[j]][ants[i].tabu[j+1]]+=Q/ants[i].m_dLength ;            Map.m_dDeltTrial[ants[i].tabu[j+1]][ants[i].tabu[j]]+=Q/ants[i].m_dLength; // G[i][j] = G[j][i]        }        Map.m_dDeltTrial[ants[i].tabu[iCityCount-1]][ants[i].tabu[0]]+=Q/ants[i].m_dLength;        Map.m_dDeltTrial[ants[i].tabu[0]][ants[i].tabu[iCityCount-1]]+=Q/ants[i].m_dLength;    }      for (i=0;i<iCityCount;i++) {        for (j=0;j<iCityCount;j++)        {            Map.m_dTrial[i][j]=(rou*Map.m_dTrial[i][j]+Map.m_dDeltTrial[i][j] );            Map.m_dDeltTrial[i][j]=0;        }    }}void project::GetAnt() { // uniformly-distributed place m ants to n towns    //randomly put ant into map    int i=0;    int city;    srand( (unsigned)time( NULL ) +rand());     for (i=0;i<iAntCount;i++) {        city = rnd(iCityCount);        ants[i].addcity(city);    }}void project::StartSearch() {    //begin to find best solution    int max=0; // times of iteration     int i;    int j;    double temp; // store shortest distance among those m ants in each iteration     int temptour[iCityCount]; // temporary the tour with the shortest distance in the current iteration     while (max<iItCount) {        for (j=0;j<iAntCount;j++) {            for (i=0;i<iCityCount-1;i++)                ants[j].move();        } // in each iteration, every ant makes iCityCount moves, completing a cycle and then updating trail intensity          for(j=0;j<iAntCount;j++) { //            ants[j].move2last();            ants[j].CalcDistance();  // CalcLengthTour of each ant, preparing for updating delta trail        }        //find out the best solution of the step and put it into temp        int t;        temp = ants[0].m_dLength;        for (t=0;t<iCityCount;t++)            temptour[t]=ants[0].tabu[t];        for(j=1; j<iAntCount; j++) {            if (temp > ants[j].m_dLength) { // update shortest distance and its tour when possible                 temp = ants[j].m_dLength;                for ( t = 0; t < iCityCount; t++ )                     temptour[t]=ants[j].tabu[t];            }        }        if(temp < m_dLengthVar) { // m_dLengthVar is a member variable of Object of Class project             m_dLengthVar = temp;            for ( t=0;t<iCityCount;t++)                besttour[t] = temptour[t];        }        printf("%4d : %f\n", max, m_dLengthVar); // # of iteration and its shortest distance found         UpdateTrial();        for(j=0;j<iAntCount;j++)            ants[j].Clear();          max++;    }    printf("The shortest route is : %f\n",m_dLengthVar); // print out the shortest path of N nodes      for ( int t=0;t<iCityCount;t++)        printf(" %d ",besttour[t]);    printf("\n");}int main() {     project TSP;     TSP.GetAnt();     TSP.StartSearch();     return 0; }



Reference:

http://www.oschina.net/code/snippet_33669_9138

0 0