C++代码:
#include
#include
#include
using namespace std;
#define N 75
double C[N][2]={
{6,25}, {7,43}, {9,56}, {10,70}, {11,28},
{12,17}, {12,38}, {15,5}, {15,14}, {15,56},
{16,19}, {17,64}, {20,30}, {21,48}, {21,45},
{21,36}, {22,53}, {22,22}, {26,29}, {26,13},
{26,59}, {27,24}, {29,39}, {30,50}, {30,20},
{30,60}, {31,76}, {33,34}, {33,44}, {35,51},
{35,16}, {35,60}, {36,6}, {36,26}, {38,33},
{40,37}, {40,66}, {40,60}, {40,20}, {41,46},
{43,26}, {44,13}, {45,42}, {45,35}, {47,66},
{48,21}, {50,30}, {50,40}, {50,50}, {50,70},
{50,4}, {50,15}, {51,42}, {52,26}, {54,38},
{54,10}, {55,34}, {55,45}, {55,50}, {55,65},
{55,57}, {55,20}, {57,72}, {59,5}, {60,15},
{62,57}, {62,48}, {62,35}, {62,24}, {64,4},
{65,27}, {66,14}, {66,8}, {67,41}, {70,64}
};
#define M 75
int NcMax =1000;
double alpha = 2, beta = 5, rou = 0.1, alpha1 = 0.1, qzero = 0.1;
double allDistance[N][N];
double Lnn;
int ChooseNextNode(int currentNode, int visitedNode[]);
double CalAdjacentDistance(int node);
double calculateDistance(int i, int j);
void calculateAllDistance();
double calculateSumOfDistance(int* tour);
class ACSAnt;
class AntColonySystem
{
private:
double info[N][N], visible[N][N];
public:
AntColonySystem()
{
}
double Transition(int i, int j);
void UpdateLocalPathRule(int i, int j);
void InitParameter(double value);
void UpdateGlobalPathRule(int* bestTour, int globalBestLength);
};
class ACSAnt
{
private:
AntColonySystem* antColony;
protected:
int startCity, cururentCity;
int allowed[N];
int Tour[N][2];
int currentTourIndex;
public:
ACSAnt(AntColonySystem* acs, int start)
{
antColony = acs;
startCity = start;
}
int* Search();
int Choose();
void MoveToNextCity(int nextCity);
};
int main()
{
time_t timer, timerl;
time(&timer);
unsigned long seed = timer;
seed %= 56000;
srand((unsigned int)seed);
calculateAllDistance();
AntColonySystem* acs = new AntColonySystem();
ACSAnt* ants[M];
for (int k = 0; k < M; k++)
{
ants[k] = new ACSAnt(acs, (int)(k%N));
}
int node = rand() % N;
Lnn = CalAdjacentDistance(node);
double initInfo = 1 / (N * Lnn);
acs->InitParameter(initInfo);
int globalTour[N][2];
double globalBestLength = 0.0;
for (int i = 0; i < NcMax; i++)
{
int localTour[N][2];
double localBestLength = 0.0;
double tourLength;
for (int j = 0; j < M; j++)
{
int* tourPath = ants[j]->Search();
tourLength = calculateSumOfDistance(tourPath);
if (tourLength < localBestLength || abs(localBestLength - 0.0) < 0.000001)
{
for (int m = 0; m< N; m++)
{
int row = *(tourPath + 2 * m);
int col = *(tourPath + 2 * m + 1);
localTour[m][0] = row;
localTour[m][1] = col;
}
localBestLength = tourLength;
}
}
if (localBestLength < globalBestLength || abs(globalBestLength - 0.0) < 0.000001)
{
for (int m = 0; m< N; m++)
{
globalTour[m][0] = localTour[m][0];
globalTour[m][1] = localTour[m][1];
}
globalBestLength = localBestLength;
}
acs->UpdateGlobalPathRule(*globalTour, globalBestLength);
cout << "第 " << i + 1 << " 迭代最优路径:" << localBestLength << " " << endl;
for (int m = 0; m< N; m++)
{
cout << localTour[m][0] << " ";
}
cout << endl;
}
cout << "全局最优路径长度:" << globalBestLength << endl;
cout << "全局最优路径:";
for (int m = 0; m< N; m++)
{
cout << globalTour[m][0] << " ";
}
cout << endl;
system("pause");
return 0;
}
double AntColonySystem::Transition(int i, int j)
{
if (i != j)
{
return (pow(info[i][j], alpha) * pow(visible[i][j], beta));
}
else
{
return 0.0;
}
}
void AntColonySystem::UpdateLocalPathRule(int i, int j)
{
info[i][j] = (1.0 - alpha1) * info[i][j] + alpha1 * (1.0 / (N * Lnn));
info[j][i] = info[i][j];
}
void AntColonySystem::InitParameter(double value)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
info[i][j] = value;
info[j][i] = value;
if (i != j)
{
visible[i][j] = 1.0 / allDistance[i][j];
visible[j][i] = visible[i][j];
}
}
}
}
void AntColonySystem::UpdateGlobalPathRule(int* bestTour, int globalBestLength)
{
for (int i = 0; i < N; i++)
{
int row = *(bestTour + 2 * i);
int col = *(bestTour + 2 * i + 1);
info[row][col] = (1.0 - rou) * info[row][col] + rou * (1.0 / globalBestLength);
info[col][row] = info[row][col];
}
}
int ChooseNextNode(int currentNode, int visitedNode[])
{
int nextNode = -1;
double shortDistance = 0.0;
for (int i = 0; i < N; i++)
{
if (1 == visitedNode[i])
{
if (shortDistance == 0.0)
{
shortDistance = allDistance[currentNode][i];
nextNode = i;
}
if (shortDistance < allDistance[currentNode][i])
{
nextNode = i;
}
}
}
return nextNode;
}
double CalAdjacentDistance(int node)
{
double sum = 0.0;
int visitedNode[N];
for (int j = 0; j < N; j++)
{
visitedNode[j] = 1;
}
visitedNode[node] = 0;
int currentNode = node;
int nextNode;
do
{
nextNode = ChooseNextNode(currentNode, visitedNode);
if (nextNode >= 0)
{
sum += allDistance[currentNode][nextNode];
currentNode = nextNode;
visitedNode[currentNode] = 0;
}
} while (nextNode >= 0);
sum += allDistance[currentNode][node];
return sum;
}
int* ACSAnt::Search()
{
cururentCity = startCity;
int toCity;
currentTourIndex = 0;
for (int i = 0; i < N; i++)
{
allowed[i] = 1;
}
allowed[cururentCity] = 0;
int endCity;
int count = 0;
do
{
count++;
endCity = cururentCity;
toCity = Choose();
if (toCity >= 0)
{
MoveToNextCity(toCity);
antColony->UpdateLocalPathRule(endCity, toCity);
cururentCity = toCity;
}
} while (toCity >= 0);
MoveToNextCity(startCity);
antColony->UpdateLocalPathRule(endCity, startCity);
return *Tour;
}
int ACSAnt::Choose()
{
int nextCity = -1;
double q = rand() / (double)RAND_MAX;
if (q <= qzero)
{
double probability = -1.0;
for (int i = 0; i < N; i++)
{
if (1 == allowed[i])
{
double prob = antColony->Transition(cururentCity, i);
if (prob > probability)
{
nextCity = i;
probability = prob;
}
}
}
}
else
{
double p = rand() / (double)RAND_MAX;
double sum = 0.0;
double probability = 0.0;
for (int i = 0; i < N; i++)
{
if (1 == allowed[i])
{
sum += antColony->Transition(cururentCity, i);
}
}
for (int j = 0; j < N; j++)
{
if (1 == allowed[j] && sum > 0)
{
probability += antColony->Transition(cururentCity, j) / sum;
if (probability >= p || (p > 0.9999 && probability > 0.9999))
{
nextCity = j;
break;
}
}
}
}
return nextCity;
}
void ACSAnt::MoveToNextCity(int nextCity)
{
allowed[nextCity] = 0;
Tour[currentTourIndex][0] = cururentCity;
Tour[currentTourIndex][1] = nextCity;
currentTourIndex++;
cururentCity = nextCity;
}
double calculateDistance(int i, int j)
{
return sqrt(pow((C[i][0]-C[j][0]),2.0) + pow((C[i][1]-C[j][1]),2.0));
}
void calculateAllDistance()
{
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
if (i != j)
{
allDistance[i][j] = calculateDistance(i, j);
allDistance[j][i] = allDistance[i][j];
}
}
}
}
double calculateSumOfDistance(int* tour)
{
double sum = 0;
for(int i = 0; i< N ;i++)
{
int row = *(tour + 2 * i);
int col = *(tour + 2* i + 1);
sum += allDistance[row][col];
}
return sum;
}
运行结果: