粒子群算法求解tsp问题 c++代码 并解释代码
时间: 2023-07-10 12:41:36 浏览: 115
粒子群算法解决TSP问题
5星 · 资源好评率100%
以下是使用粒子群算法求解TSP问题的C++代码,注释中包含了代码的解释。
```c++
#include <iostream>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 100; //最大城市数量
const int MAXM = 10000; //最大迭代次数
const double INF = 1e20; //表示无穷大
const double eps = 1e-8; //控制精度
int n, m; //城市数量和迭代次数
double w[MAXN][MAXN]; //存储城市间的距离
double ans; //记录最优解
int path[MAXN]; //记录最优解的路径
struct particle //定义粒子结构体
{
double x[MAXN]; //存储每个粒子的位置
double v[MAXN]; //存储每个粒子的速度
double p[MAXN]; //存储每个粒子的最优位置
double fp; //存储每个粒子的最优适应度
void init(); //初始化粒子
void update(); //更新粒子的位置和速度
void eval(); //计算粒子的适应度
};
particle pop[MAXM]; //存储粒子群
double g[MAXN]; //存储全局最优位置
//计算两个城市之间的距离
double dist(int i, int j)
{
return sqrt((w[i][0]-w[j][0])*(w[i][0]-w[j][0])+(w[i][1]-w[j][1])*(w[i][1]-w[j][1]));
}
//初始化函数
void init()
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
w[i][j] = dist(i,j); //计算城市间的距离
for (int i = 0; i < m; i++)
pop[i].init(); //初始化每个粒子
ans = INF; //初始化最优解
}
//粒子初始化函数
void particle::init()
{
for (int i = 0; i < n; i++)
x[i] = i;
random_shuffle(x,x+n); //随机打乱顺序
for (int i = 0; i < n; i++)
p[i] = x[i]; //初始最优位置为当前位置
fp = INF; //初始化最优适应度
for (int i = 0; i < n; i++)
v[i] = (rand()/(double)RAND_MAX-0.5)*n; //初始化速度
}
//粒子的适应度函数
void particle::eval()
{
double sum = 0;
for (int i = 0; i < n-1; i++)
sum += w[(int)x[i]][(int)x[i+1]]; //计算当前路径长度
sum += w[(int)x[n-1]][(int)x[0]];
if (sum < fp)
{
fp = sum;
for (int i = 0; i < n; i++)
p[i] = x[i]; //更新最优位置
}
}
//粒子的更新函数
void particle::update()
{
double r1 = (rand()/(double)RAND_MAX); //生成两个随机数
double r2 = (rand()/(double)RAND_MAX);
for (int i = 0; i < n; i++)
{
v[i] = v[i] + r1*(p[i]-x[i]) + r2*(g[i]-x[i]); //更新速度
if (v[i] > n) v[i] = n; //限制速度范围
if (v[i] < -n) v[i] = -n;
x[i] = x[i] + v[i]; //更新位置
}
}
//更新全局最优位置
void update_gbest()
{
for (int i = 0; i < n; i++)
g[i] = pop[0].p[i]; //先将第一个粒子的最优位置设为全局最优位置
for (int i = 1; i < m; i++)
if (pop[i].fp < ans)
{
ans = pop[i].fp;
for (int j = 0; j < n; j++)
g[j] = pop[i].p[j]; //更新全局最优位置
}
}
//主函数
int main()
{
cin >> n >> m;
srand(time(NULL));
init(); //初始化
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
pop[i].eval(); //计算每个粒子的适应度
update_gbest(); //更新全局最优位置
for (int j = 0; j < m; j++)
pop[j].update(); //更新每个粒子的位置和速度
}
for (int i = 0; i < n; i++)
path[(int)g[i]] = i; //记录最优解的路径
cout << fixed << setprecision(2) << ans << endl;
for (int i = 0; i < n; i++)
cout << path[i] << " ";
cout << endl;
return 0;
}
```
该算法的思想是将每个粒子看作一个TSP问题的解,每个粒子的位置表示一条TSP问题的解路径。粒子的速度表示粒子在当前位置上搜索最优解的方向和距离。每个粒子不断地更新自己的位置和速度,同时记录自己的最优位置和最优适应度(即路径长度)。全局最优位置则是所有粒子的最优位置中路径长度最短的那个。算法迭代一定次数后,最终的全局最优位置即为TSP问题的最优解路径。
算法的关键是如何更新粒子的位置和速度,这里使用了经典的粒子群算法的公式:
$$
v_i = v_i + r_1(p_i-x_i)+r_2(g_i-x_i)\\
x_i = x_i + v_i
$$
其中,$v_i$表示第$i$个粒子的速度,$p_i$表示第$i$个粒子的最优位置,$g_i$表示全局最优位置,$x_i$表示第$i$个粒子的当前位置,$r_1$和$r_2$是两个随机数,用于控制个体和群体的影响。在实现时,还需要对速度进行限制,以避免速度过大或过小。
阅读全文