ACO

#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]=0
public:
    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

    原文作者:蚁群算法
    原文地址: https://blog.csdn.net/u013882110/article/details/43877141
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞