蚁群算法解决TSP

#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();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值