#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<opencv2\opencv.hpp>
using namespace std;
#define size 23
int Q = 1000;
double Q0 = 100;
#define antnum 34
double alpha = 0.8;
double beta = 2;
#define cir 10000
double dispersefactor = 0.5;
#define inf 1000000000000.
#define original 100
cv::Mat background;
double dist[size][size];
double pheromone[size][size];
int pre[size][size];
string island[] = { "���˵�","��ɳ��","����̲", "����", "��Ȫ��", "����̲", "տ��̲", "������", "���⽸", "��ʯ��", "�н���", "�˻���", "���ҵ�", "��ɳ������", "��ɳ������","���ϰ�ɳ", "���", "������", "���Ͻ�", "���ý�", "���Ž�", "����","侱̽�" };
double longitude[] = { 112.35,112.25,112.24,112.73,111.68,112.47,112.56,112.03,111.71,111.79,111.2,112.52,117.76,114.71,114.06,115.44,112.96,112.83,114.28,115.54,114.57,114.22,114.08 };
double latitude[] = { 16.84,16.98,16.76,16.63,16.51,16.33,16.4,16.33,16.22,16.03,15.77,16.03,15.15,16.07,15.51,13.94,9.59,8.85,9.68,9.86,9.92,10.17,10.88 };
class point
{
public:
double x, y;
string name;
point()
{
}
void setinfor(string name, double x, double y)
{
this->name = name;
this->x = x;
this->y = y;
}
};
point islan[size];
class Ant
{
public:
double possibility[size];
int currentpos;
int time;
double pathlength;
int path[size];
Ant()
{
}
void init()
{
currentpos = rand() % size;
time = 0;
pathlength = 0;
path[0] = currentpos;
for (int i = 0; i < size; i++)
{
possibility[i] = 0;
}
}
bool haspassed(int nextpos)
{
for (int i = 0; i < time; i++)
if (nextpos == path[i])
return true;
return false;
}
int nextpos()
{
double pm = 0;
for (int i = 0; i < size; i++)
if (haspassed(i) == false)
pm += possibility[i]=pow(pheromone[currentpos][i], alpha)*pow(dist[currentpos][i], -beta);
else possibility[i] = 0;
int poss[size];
int sum = 0;
for (int i = 0; i < size; i++)
{
possibility[i] /= pm;
sum+=poss[i] = (int)(possibility[i]*cir);
}
int x;
int randnum = rand() % sum;
sum = 0;
for (int i = 0; i < size; i++)
{
sum += poss[i];
if (randnum < sum)
return i;
}
int i = 0;
while (haspassed(i) == true)i++;
return i;
}
void move()
{
time++;
int next= nextpos();
path[time] = next;
pathlength += dist[currentpos][next];
currentpos = next;
if (time == size - 1)
{
pathlength += dist[next][path[0]];
time = 0;
}
}
bool hasgonethrough(int x, int y)
{
for (int i = 0; i < time; i++)
{
if (path[i] == x&&path[(i + 1) % size] == y)
return true;
}
return false;
}
};
void getpath(int x, int y, int&num, int path[])
{
num = 0;
int index = y;
path[0] = y;
do
{
num++;
index = pre[x][index];
path[num] =index;
} while (index!= x);
for (int i = 0; i <=num/ 2; i++)
{
int temp = path[i];
path[i] = path[num - i];
path[num - i] = temp;
}
}
class antColony
{
public:
Ant ant[antnum];
double optimal;
int x;
int n0;
int opath[size];
int cnt;
int flag;
antColony()
{
}
void init()
{
flag = 0;
cnt == 0;
optimal = inf;
n0 = 5;
}
void findoptimal()
{
double min = optimal;
for (int i = 0; i < antnum; i++)
if (ant[i].pathlength < min)
{
min = ant[i].pathlength;
x = i;
for (int j = 0; j < size; j++)
opath[j] = ant[x].path[j];
flag = 0;
}
if (fabs(min - optimal) < 0.000001)
flag++;
optimal = min;
}
void run(int n)
{
for (int i = 0; i < n; i++)
{
round(1000);
show();
draw();
}
}
void show()
{
cout << optimal << "ǧ��" << " ";
for (int i = 0; i < size; i++)
cout << islan[opath[i]].name << " ";
cout << endl;
cout << alpha << " " << beta << " " << dispersefactor << endl;
}
void update()
{
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
double delta = 0;
for (int k = 0; k < antnum; k++)
{
if (ant[k].hasgonethrough(i, j) == true)
delta += Q / ant[k].pathlength;
}
pheromone[i][j] = pheromone[i][j] * dispersefactor + delta;
}
}
void updatefactor()
{
cnt = flag / 1000;
if (cnt> n0 + 1)
{
dispersefactor =0.7* pow(dispersefactor, 0.5);
//Q = -Q0*(cnt - n0);
}
else
{
dispersefactor = 0.8;
}
}
void round(int total)
{
for (int i = 0; i < total; i++)
{
for (int j = 0; j < antnum; j++)
{
ant[j].init();
for (int k = 0; k < size; k++)
{
ant[j].move();
}
}
update();
updatefactor();
findoptimal();
}
}
void draw()
{
int index[size];
int num = 0;
cv::Mat back = background.clone();
for (int i = 0; i < size; i++)
{
getpath(opath[i], opath[(i + 1) % size], num, index);
for (int j = 0; j < num; j++)
cv::line(back, cv::Point(islan[index[j + 1]].x, islan[index[j + 1]].y), cv::Point(islan[index[j]].x, islan[index[j]].y), cv::Scalar(0, 0, 255));
}
cv::imshow("wall", back);
cv::waitKey(100);
}
};
void init()
{
cout << "������ȫͼȨ����" << endl;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
cin >> dist[i][j];
pheromone[i][j] = original;
}
cout << "����������ȫͼ�ڵ�ǰ������" << endl;
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
{
cin >> pre[i][j];
}
cout << "���Žʼ����" << endl;
}
void drawispo()
{
for (int i = 0; i < size; i++)
{
cv::circle(background, cv::Point(islan[i].x, islan[i].y), 5, cv::Scalar(125, 123, 85));
}
}
int main()
{
background = cv::imread("back.png");
double hight = 111 * 10, width = 111 * 7, maph = 550, mapw = 330, baselong = 111., baselati = 18;
for (int i = 0; i < size; i++)
islan[i].setinfor(island[i], (longitude[i] - baselong) * 111 / hight*maph, (baselati - latitude[i]) * 111 / width*mapw);
init();
drawispo();
srand((unsigned)(time(0)));
antColony ac;
ac.init();
ac.run(100);
getchar();
getchar();
}
蚁群算法解决TSP
原文作者:蚁群算法
原文地址: https://blog.csdn.net/Toxic_code_generator/article/details/76855864
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/Toxic_code_generator/article/details/76855864
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。