人工鱼群算法求解TSP旅行商问题C++(2020.11.15)

1、输入数据文件:bayg29.tsp

   1    1150.0  1760.0
   2     630.0  1660.0
   3      40.0  2090.0
   4     750.0  1100.0
   5     750.0  2030.0
   6    1030.0  2070.0
   7    1650.0   650.0
   8    1490.0  1630.0
   9     790.0  2260.0
  10     710.0  1310.0
  11     840.0   550.0
  12    1170.0  2300.0
  13     970.0  1340.0
  14     510.0   700.0
  15     750.0   900.0
  16    1280.0  1200.0
  17     230.0   590.0
  18     460.0   860.0
  19    1040.0   950.0
  20     590.0  1390.0
  21     830.0  1770.0
  22     490.0   500.0
  23    1840.0  1240.0
  24    1260.0  1500.0
  25    1280.0   790.0
  26     490.0  2130.0
  27    1460.0  1420.0
  28    1260.0  1910.0
  29     360.0  1980.0

2、头文件

#include <iostream>
#include <fstream>
#include <string>
#include <random>
#include <time.h>
using namespace std;

3、所需的类

        所需的类包括城市类City、包含城市的地图类Graph、人工鱼类AF、人工鱼群算法类AFA。

3.1 城市类City

class City
{
    
    
public:
	string name;//城市名称
	double x, y;//城市点的二维坐标
	void shuchu()
	{
    
    
		std::cout << name + ":" << "(" << x << "," << y << ")" << endl;
	}
};

3.2 包含城市的地图类Graph

class Graph
{
    
    
public:
	int Citycount;
	City *city;//城市数组
	double distance[citycount][citycount];//城市间的距离矩阵
	void Readcoordinatetxt(string txtfilename)//读取城市坐标文件的函数
	{
    
    
		Citycount = citycount;
		city = new City[Citycount];
		ifstream myfile(txtfilename, ios::in);
		double x = 0, y = 0;
		int z = 0;
		if (!myfile.fail())
		{
    
    
			int i = 0;
			while (!myfile.eof() && (myfile >> z >> x >> y))
			{
    
    
				city[i].name = to_string(_Longlong(z));//城市名称转化为字符串
				city[i].x = x; city[i].y = y;
				i++;
			}
		}
		else
			cout << "文件不存在";
		myfile.close();//计算城市距离矩阵
		for (int i = 0; i < citycount; i++)
			for (int j = 0; j < citycount; j++)
			{
    
    
				distance[i][j] = sqrt((pow((city[i].x - city[j].x), 2) + pow((city[i].y - city[j].y), 2)) / 10.0);//计算城市ij之间的伪欧式距离
				if (round(distance[i][j] < distance[i][j]))distance[i][j] = round(distance[i][j]) + 1;
				else distance[i][j] = round(distance[i][j]);
			}
	}
	void shuchu()
	{
    
    
		cout << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
		for (int i = 0; i < citycount; i++)
			city[i].shuchu();
		cout << "距离矩阵: " << endl;
		for (int i = 0; i < citycount; i++)
		{
    
    
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					std::cout << distance[i][j] << endl;
				else
					std::cout << distance[i][j] << "  ";
			}
		}
	}
};

3.3 人工鱼类AF

class AF
{
    
    
public:
	int dimension;//个体变量维数
	int *x;
	void Init(int Dim)//初始化函数
	{
    
    
		dimension = Dim;
		x = new int[dimension];
		x = Random_N(dimension);
	}
	double fitfunctionvalue()//个体适应值计算函数,即计算路径对应的距离
	{
    
    
		double fitvalue = 0;
		for (int j = 0; j < dimension - 1; j++)
			fitvalue += Map_City.distance[*(x + j) - 1][*(x + j + 1) - 1];
		fitvalue += Map_City.distance[*(x + dimension - 1) - 1][*x - 1];
		return fitvalue;
	}
	void shuchu()
	{
    
    
		for (int j = 0; j < dimension; j++)
		{
    
    
			if(j==0)
				std::cout <<"f("<< x[j] << ",";
			else if(j==dimension-1)
				std::cout<< x[j] << ") =";
			else
				std::cout<<x[j] << ",";
		}
		std::cout <<fitfunctionvalue()<< endl;
	}
};

3.4 人工鱼群算法类AFA

class AFA
{
    
    
public:
	int N;//种群规模
	int Dimension;//维数
	double step = 0;
	double visual = 0;
	double try_number = 0;
	double delta = 0;
	AF *af;
	AF Bestfish;//公告板最优解
	void Init(int num, int Dim, double Step, double Visual, double Try_number, double Delta)//初始化函数
	{
    
    
		N = num;
		Dimension = Dim;
		step = Step;
		visual = Visual;
		try_number = Try_number;
		delta = Delta;
		af = new AF[N];
		for (int i = 0; i < N; i++)
			(af + i)->Init(Dimension);
		Bestfish.Init(Dimension);
		double bestfitness = af->fitfunctionvalue();
		for (int j = 0; j < Dimension; j++)
			Bestfish.x[j] = af->x[j];
		for (int i = 0; i < N; i++)
		{
    
    
			if ((af + i)->fitfunctionvalue() < bestfitness)
			{
    
    
				bestfitness = (af + i)->fitfunctionvalue();
				for (int j = 0; j < Dimension; j++)
					Bestfish.x[j] = (af + i)->x[j];
			}
		}
	}
	double Distance(AF af1, AF af2)//计算两条鱼距离的函数
	{
    
    
		double dist = 0;
		for (int i = 0; i < Dimension; i++)
			dist += pow(af1.x[i] - af2.x[i], 2.0);
		dist = sqrt(dist / float(Dimension));
		return dist;
	}
	void prey(int id)//觅食行为
	{
    
    
		AF AFNew;
		AFNew.Init(Dimension);
		for (int i = 0; i < try_number; i++)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				AFNew.x[j] = (af + id)->x[j] + r(random) * visual;
			double Yi = 0, Yj = 0;
			Yi = (af + id)->fitfunctionvalue();
			Yj = AFNew.fitfunctionvalue();
			if (Yi > Yj)
			{
    
    
				for (int j = 0; j < Dimension; j++)
					(af + id)->x[j] = round((af + id)->x[j] + r(random)*step*(AFNew.x[j] - (af + id)->x[j]) / Distance(AFNew, *(af + id)));
			}
			else
			{
    
    
				for (int j = 0; j < Dimension; j++)
					(af + id)->x[j] = round((af + id)->x[j] + r(random)*step);
			}
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
	}
	void swarm(int id)//聚群行为
	{
    
    
		AF AFXc;
		AFXc.Init(Dimension);
		for (int j = 0; j < Dimension; j++) AFXc.x[j] = 0;
		double nf = 0;
		for (int i = 0; i < N; i++)
			if ((Distance(*(af + id), *(af + i)) < visual) && (Distance(*(af + id), *(af + i)) != 0))
			{
    
    
				nf++;
				for (int j = 0; j < Dimension; j++)
					AFXc.x[j] += (af + i)->x[j];
			}
		for (int j = 0; j < Dimension; j++)
			AFXc.x[j] = AFXc.x[j] / nf;//计算邻域伙伴的中心位置
		double Yc = AFXc.fitfunctionvalue(), Yi = (af + id)->fitfunctionvalue();
		if (Yc / nf < delta*Yi)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				(af + id)->x[j] = (af + id)->x[j] + r(random)*step*(AFXc.x[j] - (af + id)->x[j]) / Distance(AFXc, *(af + id));
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
		else
			prey(id);
	}
	void follow(int id)//追尾行为
	{
    
    
		double Ymin = INFINITY;
		AF AFXmin;
		AFXmin.Init(Dimension);
		for (int j = 0; j < Dimension; j++) AFXmin.x[j] = 0;
		for (int i = 0; i < N; i++)
		{
    
    
			double dij = Distance(*(af + id), *(af + i)), Yj = (af + i)->fitfunctionvalue();
			if (dij != 0 && dij<visual && Yj <Ymin)
			{
    
    
				Ymin = Yj;
				for (int j = 0; j < Dimension; j++)
					AFXmin.x[j] = (af + i)->x[j];
			}
		}
		double nf = 0;
		for (int i = 0; i < N; i++)
		{
    
    
			double dminj = Distance(AFXmin, *(af + i));
			if (dminj != 0 && dminj < visual)
				nf++;
		}
		double Yi = (af + id)->fitfunctionvalue();
		if (Ymin / nf < delta *Yi)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				(af + id)->x[j] = (af + id)->x[j] + r(random)*step*(AFXmin.x[j] - (af + id)->x[j]) / Distance(AFXmin, *(af + id));
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
		else
			prey(id);
	}
	void evaluate(int id)
	{
    
    
		if ((af + id)->fitfunctionvalue() < Bestfish.fitfunctionvalue())
		{
    
    
			for (int j = 0; j < Dimension; j++)
				Bestfish.x[j] = (af + id)->x[j];
		}
	}
	void DoAFA(int num, int Dim, double Step, double Visual, double Try_number, double Delta, int Itetime,string filename)
	{
    
    
		ofstream outfile;
		outfile.open("result.txt", ios::trunc);
		Map_City.Readcoordinatetxt(filename);
		Map_City.shuchu();
		outfile << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
		for (int i = 0; i < citycount; i++)
			outfile << Map_City.city[i].name << " " << Map_City.city[i].x << " " << Map_City.city[i].y << endl;
		outfile << "距离矩阵: " << endl;
		for (int i = 0; i < citycount; i++)
		{
    
    
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << Map_City.distance[i][j] << endl;
				else
					outfile << Map_City.distance[i][j] << "  ";
			}
		}
		Init(num, Dim, Step, Visual, Try_number, Delta);
		Shuchu();
		outfile << "初始化后的鱼群如下:" << endl;
		for (int i = 0; i < N; i++)
		{
    
    
			outfile << "鱼" << i + 1 << "->";
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << (af + i)->x[j] << ") = " << (af+i)->fitfunctionvalue() << endl;
				else if (j == 0)
					outfile << "f(" << (af + i)->x[j] << ",";
				else
					outfile << (af + i)->x[j] << ",";
			}
		}
		outfile << "初始化后的最佳鱼为:";
		for (int j = 0; j < citycount; j++)
		{
    
    
			if (j == citycount - 1)
				outfile << Bestfish.x[j] << ") = " << Bestfish.fitfunctionvalue() << endl;
			else if (j == 0)
				outfile << "f(" << Bestfish.x[j] << ",";
			else
				outfile << Bestfish.x[j] << ",";
		}
		for (int t = 0; t < Itetime; t++)
		{
    
    
			for (int i = 0; i < N; i++)
			{
    
    
				prey(i);
				swarm(i);
				follow(i);
				evaluate(i);
			}
			std::cout << "第" << t + 1 << "次迭代最优位置为Bestfish:";
			Bestfish.shuchu();
			outfile << "第" << t + 1 << "次迭代后的鱼群如下:" << endl;
			for (int i = 0; i < N; i++)
			{
    
    
				outfile << "鱼" << i + 1 << "->";
				for (int j = 0; j < citycount; j++)
				{
    
    
					if (j == citycount - 1)
						outfile << (af + i)->x[j] << ") = " << (af + i)->fitfunctionvalue() << endl;
					else if (j == 0)
						outfile << "f(" << (af + i)->x[j] << ",";
					else
						outfile << (af + i)->x[j] << ",";
				}
			}
			outfile << "第" << t + 1 << "次迭代后的最优位置如下:" << endl;
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << Bestfish.x[j] << ") = " << Bestfish.fitfunctionvalue() << endl;
				else if (j == 0)
					outfile << "f(" << Bestfish.x[j] << ",";
				else
					outfile << Bestfish.x[j] << ",";
			}
		}
		std::cout << "迭代结束后最优位置为Bestfish:";
		Bestfish.shuchu();
	}
	void Shuchu()
	{
    
    
		for (int i = 0; i < N; i++)
		{
    
    
			std::cout << "第" << i + 1 << "条鱼: ";
			(af + i)->shuchu();
		}
	}
};

4、自定义函数

        自定义函数包括:四舍五入取整函数、路径随机初始化函数、调整鱼群路径有效性的函数。

4.1 四舍五入取整函数

double round(double r) {
    
     return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }

4.2 路径随机初始化函数

int * Random_N(int n)//随机生成TSP问题的一个可行解的函数
{
    
    
	int *geti;
	geti = new int[n];
	int j = 0;
	while (j<n)
	{
    
    
		while (true)
		{
    
    
			int flag = -1;
			int temp = rand() % n + 1;
			if (j > 0)
			{
    
    
				int k = 0;
				for (; k < j; k++)
				{
    
    
					if (temp == *(geti + k))break;
				}
				if (k == j)
				{
    
    
					*(geti + j) = temp;
					flag = 1;
				}
			}
			else
			{
    
    
				*(geti + j) = temp;
				flag = 1;
			}
			if (flag == 1)break;
		}
		j++;
	}
	return geti;
}

4.3 调整路径有效性的函数

void Adjuxt_validParticle(int x[citycount])//调整蜜源路径有效性的函数,使得蜜源的位置符合TSP问题解的一个排列
{
    
    
	int route[citycount];//1-citycount
	bool flag[citycount];//对应route数组中是否在位置中存在的数组,参考数组为route
	int biaoji[citycount];//对每个元素进行标记的数组,参考数组为粒子位置x
	for (int j = 0; j < citycount; j++)
	{
    
    
		route[j] = j + 1;
		flag[j] = false;
		biaoji[j] = 0;
	}
	//首先判断位置中是否有某个城市且唯一,若有且唯一,则对应flag的值为true,
	for (int j = 0; j < citycount; j++)
	{
    
    
		int num = 0;
		for (int k = 0; k < citycount; k++)
		{
    
    
			if (x[k] == route[j])
			{
    
    
				biaoji[k] = 1;//说明k号元素对应的城市在route中,并且是第一次出现才进行标记
				num++; break;
			}
		}
		if (num == 0) flag[j] = false;//路线中没有route[j]这个城市
		else if (num == 1) flag[j] = true;//路线中有route[j]这个城市
	}
	for (int k = 0; k < citycount; k++)
	{
    
    
		if (flag[k] == false)//路线中没有route[k]这个城市,需要将这个城市加入到路线中
		{
    
    
			int i = 0;
			for (; i < citycount; i++)
			{
    
    
				if (biaoji[i] != 1)break;
			}
			x[i] = route[k];//对于标记为0的进行替换
			biaoji[i] = 1;
		}
	}
}

5、全局变量

const int citycount = 29;
int Xmax = citycount, Xmin = 1;//变量的可行域
std::default_random_engine random((unsigned int)time(NULL));
std::uniform_real_distribution<double> u(Xmin, Xmax); //随机数分布对象
std::uniform_real_distribution<double> r(0, 1); //随机数分布对象
Graph Map_City;//定义全局对象图,放在Graph类后

6、主函数

int main()
{
    
    
	system("mode con cols=200");
	system("color fc");
	std::cout << "人工鱼群算法求解TSP旅行商问题!" << endl;
	AFA yq;
	while (true)
	{
    
    
		int num = 0;
		std::cout << "请输入迭代的次数:";
		cin >> num;
		if (num == 0)break;
		else yq.DoAFA(20, 29, 2, 100, 10, 0.618, num, "E:\\计算智能代码\\AFA_TSP\\AFA_TSP\\bayg29.tsp");
	}
	system("pause");
	return 0;
}

7、运行结果

7.1控制台运行结果

在这里插入图片描述

7.2 生成的result.txt文件结果

在这里插入图片描述
在这里插入图片描述

8、MATLAB绘制最优路径结果

在这里插入图片描述

附录(完整代码)

#include <iostream>
#include <fstream>
#include <string>
#include <random>
#include <time.h>
using namespace std;
const int citycount = 29;
int Xmax = citycount, Xmin = 1;//变量的可行域
std::default_random_engine random((unsigned int)time(NULL));
std::uniform_real_distribution<double> u(Xmin, Xmax); //随机数分布对象
std::uniform_real_distribution<double> r(0, 1); //随机数分布对象
class City
{
    
    
public:
	string name;//城市名称
	double x, y;//城市点的二维坐标
	void shuchu()
	{
    
    
		std::cout << name + ":" << "(" << x << "," << y << ")" << endl;
	}
};
class Graph
{
    
    
public:
	int Citycount;
	City *city;//城市数组
	double distance[citycount][citycount];//城市间的距离矩阵
	void Readcoordinatetxt(string txtfilename)//读取城市坐标文件的函数
	{
    
    
		Citycount = citycount;
		city = new City[Citycount];
		ifstream myfile(txtfilename, ios::in);
		double x = 0, y = 0;
		int z = 0;
		if (!myfile.fail())
		{
    
    
			int i = 0;
			while (!myfile.eof() && (myfile >> z >> x >> y))
			{
    
    
				city[i].name = to_string(_Longlong(z));//城市名称转化为字符串
				city[i].x = x; city[i].y = y;
				i++;
			}
		}
		else
			cout << "文件不存在";
		myfile.close();//计算城市距离矩阵
		for (int i = 0; i < citycount; i++)
			for (int j = 0; j < citycount; j++)
			{
    
    
				distance[i][j] = sqrt((pow((city[i].x - city[j].x), 2) + pow((city[i].y - city[j].y), 2)) / 10.0);//计算城市ij之间的伪欧式距离
				if (round(distance[i][j] < distance[i][j]))distance[i][j] = round(distance[i][j]) + 1;
				else distance[i][j] = round(distance[i][j]);
			}
	}
	void shuchu()
	{
    
    
		cout << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
		for (int i = 0; i < citycount; i++)
			city[i].shuchu();
		cout << "距离矩阵: " << endl;
		for (int i = 0; i < citycount; i++)
		{
    
    
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					std::cout << distance[i][j] << endl;
				else
					std::cout << distance[i][j] << "  ";
			}
		}
	}
};
Graph Map_City;//定义全局对象图,放在Graph类后
double round(double r) {
    
     return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }
void Adjuxt_validParticle(int x[citycount])//调整蜜源路径有效性的函数,使得蜜源的位置符合TSP问题解的一个排列
{
    
    
	int route[citycount];//1-citycount
	bool flag[citycount];//对应route数组中是否在位置中存在的数组,参考数组为route
	int biaoji[citycount];//对每个元素进行标记的数组,参考数组为粒子位置x
	for (int j = 0; j < citycount; j++)
	{
    
    
		route[j] = j + 1;
		flag[j] = false;
		biaoji[j] = 0;
	}
	//首先判断位置中是否有某个城市且唯一,若有且唯一,则对应flag的值为true,
	for (int j = 0; j < citycount; j++)
	{
    
    
		int num = 0;
		for (int k = 0; k < citycount; k++)
		{
    
    
			if (x[k] == route[j])
			{
    
    
				biaoji[k] = 1;//说明k号元素对应的城市在route中,并且是第一次出现才进行标记
				num++; break;
			}
		}
		if (num == 0) flag[j] = false;//路线中没有route[j]这个城市
		else if (num == 1) flag[j] = true;//路线中有route[j]这个城市
	}
	for (int k = 0; k < citycount; k++)
	{
    
    
		if (flag[k] == false)//路线中没有route[k]这个城市,需要将这个城市加入到路线中
		{
    
    
			int i = 0;
			for (; i < citycount; i++)
			{
    
    
				if (biaoji[i] != 1)break;
			}
			x[i] = route[k];//对于标记为0的进行替换
			biaoji[i] = 1;
		}
	}
}
int * Random_N(int n)//随机生成TSP问题的一个可行解的函数
{
    
    
	int *geti;
	geti = new int[n];
	int j = 0;
	while (j<n)
	{
    
    
		while (true)
		{
    
    
			int flag = -1;
			int temp = rand() % n + 1;
			if (j > 0)
			{
    
    
				int k = 0;
				for (; k < j; k++)
				{
    
    
					if (temp == *(geti + k))break;
				}
				if (k == j)
				{
    
    
					*(geti + j) = temp;
					flag = 1;
				}
			}
			else
			{
    
    
				*(geti + j) = temp;
				flag = 1;
			}
			if (flag == 1)break;
		}
		j++;
	}
	return geti;
}
class AF
{
    
    
public:
	int dimension;//个体变量维数
	int *x;
	void Init(int Dim)//初始化函数
	{
    
    
		dimension = Dim;
		x = new int[dimension];
		x = Random_N(dimension);
	}
	double fitfunctionvalue()//个体适应值计算函数,即计算路径对应的距离
	{
    
    
		double fitvalue = 0;
		for (int j = 0; j < dimension - 1; j++)
			fitvalue += Map_City.distance[*(x + j) - 1][*(x + j + 1) - 1];
		fitvalue += Map_City.distance[*(x + dimension - 1) - 1][*x - 1];
		return fitvalue;
	}
	void shuchu()
	{
    
    
		for (int j = 0; j < dimension; j++)
		{
    
    
			if(j==0)
				std::cout <<"f("<< x[j] << ",";
			else if(j==dimension-1)
				std::cout<< x[j] << ") =";
			else
				std::cout<<x[j] << ",";
		}
		std::cout <<fitfunctionvalue()<< endl;
	}
};

class AFA
{
    
    
public:
	int N;//种群规模
	int Dimension;//维数
	double step = 0;
	double visual = 0;
	double try_number = 0;
	double delta = 0;
	AF *af;
	AF Bestfish;//公告板最优解
	void Init(int num, int Dim, double Step, double Visual, double Try_number, double Delta)//初始化函数
	{
    
    
		N = num;
		Dimension = Dim;
		step = Step;
		visual = Visual;
		try_number = Try_number;
		delta = Delta;
		af = new AF[N];
		for (int i = 0; i < N; i++)
			(af + i)->Init(Dimension);
		Bestfish.Init(Dimension);
		double bestfitness = af->fitfunctionvalue();
		for (int j = 0; j < Dimension; j++)
			Bestfish.x[j] = af->x[j];
		for (int i = 0; i < N; i++)
		{
    
    
			if ((af + i)->fitfunctionvalue() < bestfitness)
			{
    
    
				bestfitness = (af + i)->fitfunctionvalue();
				for (int j = 0; j < Dimension; j++)
					Bestfish.x[j] = (af + i)->x[j];
			}
		}
	}
	double Distance(AF af1, AF af2)//计算两条鱼距离的函数
	{
    
    
		double dist = 0;
		for (int i = 0; i < Dimension; i++)
			dist += pow(af1.x[i] - af2.x[i], 2.0);
		dist = sqrt(dist / float(Dimension));
		return dist;
	}
	void prey(int id)//觅食行为
	{
    
    
		AF AFNew;
		AFNew.Init(Dimension);
		for (int i = 0; i < try_number; i++)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				AFNew.x[j] = (af + id)->x[j] + r(random) * visual;
			double Yi = 0, Yj = 0;
			Yi = (af + id)->fitfunctionvalue();
			Yj = AFNew.fitfunctionvalue();
			if (Yi > Yj)
			{
    
    
				for (int j = 0; j < Dimension; j++)
					(af + id)->x[j] = round((af + id)->x[j] + r(random)*step*(AFNew.x[j] - (af + id)->x[j]) / Distance(AFNew, *(af + id)));
			}
			else
			{
    
    
				for (int j = 0; j < Dimension; j++)
					(af + id)->x[j] = round((af + id)->x[j] + r(random)*step);
			}
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
	}
	void swarm(int id)//聚群行为
	{
    
    
		AF AFXc;
		AFXc.Init(Dimension);
		for (int j = 0; j < Dimension; j++) AFXc.x[j] = 0;
		double nf = 0;
		for (int i = 0; i < N; i++)
			if ((Distance(*(af + id), *(af + i)) < visual) && (Distance(*(af + id), *(af + i)) != 0))
			{
    
    
				nf++;
				for (int j = 0; j < Dimension; j++)
					AFXc.x[j] += (af + i)->x[j];
			}
		for (int j = 0; j < Dimension; j++)
			AFXc.x[j] = AFXc.x[j] / nf;//计算邻域伙伴的中心位置
		double Yc = AFXc.fitfunctionvalue(), Yi = (af + id)->fitfunctionvalue();
		if (Yc / nf < delta*Yi)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				(af + id)->x[j] = (af + id)->x[j] + r(random)*step*(AFXc.x[j] - (af + id)->x[j]) / Distance(AFXc, *(af + id));
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
		else
			prey(id);
	}
	void follow(int id)//追尾行为
	{
    
    
		double Ymin = INFINITY;
		AF AFXmin;
		AFXmin.Init(Dimension);
		for (int j = 0; j < Dimension; j++) AFXmin.x[j] = 0;
		for (int i = 0; i < N; i++)
		{
    
    
			double dij = Distance(*(af + id), *(af + i)), Yj = (af + i)->fitfunctionvalue();
			if (dij != 0 && dij<visual && Yj <Ymin)
			{
    
    
				Ymin = Yj;
				for (int j = 0; j < Dimension; j++)
					AFXmin.x[j] = (af + i)->x[j];
			}
		}
		double nf = 0;
		for (int i = 0; i < N; i++)
		{
    
    
			double dminj = Distance(AFXmin, *(af + i));
			if (dminj != 0 && dminj < visual)
				nf++;
		}
		double Yi = (af + id)->fitfunctionvalue();
		if (Ymin / nf < delta *Yi)
		{
    
    
			for (int j = 0; j < Dimension; j++)
				(af + id)->x[j] = (af + id)->x[j] + r(random)*step*(AFXmin.x[j] - (af + id)->x[j]) / Distance(AFXmin, *(af + id));
			Adjuxt_validParticle((af + id)->x);//对个体进行有效性调整,使之符合TSP问题的一个可行有效解
		}
		else
			prey(id);
	}
	void evaluate(int id)
	{
    
    
		if ((af + id)->fitfunctionvalue() < Bestfish.fitfunctionvalue())
		{
    
    
			for (int j = 0; j < Dimension; j++)
				Bestfish.x[j] = (af + id)->x[j];
		}
	}
	void DoAFA(int num, int Dim, double Step, double Visual, double Try_number, double Delta, int Itetime,string filename)
	{
    
    
		ofstream outfile;
		outfile.open("result.txt", ios::trunc);
		Map_City.Readcoordinatetxt(filename);
		Map_City.shuchu();
		outfile << "城市名称 " << "坐标x" << " " << "坐标y" << endl;
		for (int i = 0; i < citycount; i++)
			outfile << Map_City.city[i].name << " " << Map_City.city[i].x << " " << Map_City.city[i].y << endl;
		outfile << "距离矩阵: " << endl;
		for (int i = 0; i < citycount; i++)
		{
    
    
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << Map_City.distance[i][j] << endl;
				else
					outfile << Map_City.distance[i][j] << "  ";
			}
		}
		Init(num, Dim, Step, Visual, Try_number, Delta);
		Shuchu();
		outfile << "初始化后的鱼群如下:" << endl;
		for (int i = 0; i < N; i++)
		{
    
    
			outfile << "鱼" << i + 1 << "->";
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << (af + i)->x[j] << ") = " << (af+i)->fitfunctionvalue() << endl;
				else if (j == 0)
					outfile << "f(" << (af + i)->x[j] << ",";
				else
					outfile << (af + i)->x[j] << ",";
			}
		}
		outfile << "初始化后的最佳鱼为:";
		for (int j = 0; j < citycount; j++)
		{
    
    
			if (j == citycount - 1)
				outfile << Bestfish.x[j] << ") = " << Bestfish.fitfunctionvalue() << endl;
			else if (j == 0)
				outfile << "f(" << Bestfish.x[j] << ",";
			else
				outfile << Bestfish.x[j] << ",";
		}
		for (int t = 0; t < Itetime; t++)
		{
    
    
			for (int i = 0; i < N; i++)
			{
    
    
				prey(i);
				swarm(i);
				follow(i);
				evaluate(i);
			}
			std::cout << "第" << t + 1 << "次迭代最优位置为Bestfish:";
			Bestfish.shuchu();
			outfile << "第" << t + 1 << "次迭代后的鱼群如下:" << endl;
			for (int i = 0; i < N; i++)
			{
    
    
				outfile << "鱼" << i + 1 << "->";
				for (int j = 0; j < citycount; j++)
				{
    
    
					if (j == citycount - 1)
						outfile << (af + i)->x[j] << ") = " << (af + i)->fitfunctionvalue() << endl;
					else if (j == 0)
						outfile << "f(" << (af + i)->x[j] << ",";
					else
						outfile << (af + i)->x[j] << ",";
				}
			}
			outfile << "第" << t + 1 << "次迭代后的最优位置如下:" << endl;
			for (int j = 0; j < citycount; j++)
			{
    
    
				if (j == citycount - 1)
					outfile << Bestfish.x[j] << ") = " << Bestfish.fitfunctionvalue() << endl;
				else if (j == 0)
					outfile << "f(" << Bestfish.x[j] << ",";
				else
					outfile << Bestfish.x[j] << ",";
			}
		}
		std::cout << "迭代结束后最优位置为Bestfish:";
		Bestfish.shuchu();
	}
	void Shuchu()
	{
    
    
		for (int i = 0; i < N; i++)
		{
    
    
			std::cout << "第" << i + 1 << "条鱼: ";
			(af + i)->shuchu();
		}
	}
};
int main()
{
    
    
	system("mode con cols=200");
	system("color fc");
	std::cout << "人工鱼群算法求解TSP旅行商问题!" << endl;
	AFA yq;
	while (true)
	{
    
    
		int num = 0;
		std::cout << "请输入迭代的次数:";
		cin >> num;
		if (num == 0)break;
		else yq.DoAFA(20, 29, 2, 100, 10, 0.618, num, "E:\\计算智能代码\\AFA_TSP\\AFA_TSP\\bayg29.tsp");
	}
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jing_zhong/article/details/109711671