#include <iostream>
using namespace std;
const int Inf = 10000000;//定义一个比较大的值
const int number = 12;//度
int information[2][number] = {{1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4}, {2, 3, 4, 1, 3, 4, 1, 2, 4, 1, 2, 3}};//边
double Distance[number] = {30, 6, 4, 10, 5, 10, 6, 5, 20, 4, 10, 20};//距离
class Traveling {
private:
int _city_number;//城市数
double **_city_array;//距离矩阵
int *_Best_solution;//最优解
double _Best_length;//最短长度
int *_solution;//解
public:
Traveling(int city_number = 0):_city_number(city_number), _Best_length(Inf)//初始化数据
{
_Best_solution = new int[_city_number];
_solution = new int[_city_number];
_city_array = new double*[_city_number];
for(int i = 0; i < _city_number; i++)
{
_city_array[i] = new double[_city_number];
for(int j = 0; j < _city_number; j++)
_city_array[i][j] = Inf;
}
for(int i = 0; i < number; i++)
_city_array[information[0][i] - 1][information[1][i] - 1] = Distance[i];
for(int i = 0; i < _city_number; i++)
_solution[i] = i;
Backtrack(1, 0);//调用回溯函数
Print();//输出最优
}
~Traveling()//析构函数
{
delete []_solution;
delete []_Best_solution;
for(int i = 0; i < _city_number; i++)
delete[]_city_array[i];
delete[](_city_array);
}
bool OK(int t)//约束函数(判断两顶点是否有边相连)
{
if(t == _city_number - 1)//最后一个顶点特殊判断为最后两个点的长度和最后一个点和第一个点
if(_city_array[_solution[t]][_solution[t-1]] != Inf && _city_array[_solution[t]][_solution[0]] != Inf)
return true;
if(t != _city_number - 1)
if(_city_array[_solution[t]][_solution[t-1]] != Inf)
return true;
return false;
}
double is_best(int t, double length)//限界函数(判断是否能够取得更优值)没有返回-1
{
if(t == _city_number - 1)//最后一个点特殊判断,为最后两个点的长度和最后一个点和第一个点
if(_city_array[_solution[t]][_solution[t - 1]] + length + _city_array[_solution[0]][_solution[t]] < _Best_length)
return (_city_array[_solution[t]][_solution[t - 1]] + length + _city_array[_solution[0]][_solution[t]]);
if(t != _city_number - 1)
if(_city_array[_solution[t]][_solution[t - 1]] + length < _Best_length)
return (_city_array[_solution[t]][_solution[t - 1]] + length);
return -1;
}
void swap(int t1, int t2)//交换函数
{
int temp = _solution[t1];
_solution[t1] = _solution[t2];
_solution[t2] = temp;
}
void Backtrack(int t, double length)//回溯函数
{
if(t >= _city_number)//当获得最后点时更新解
{
for(int i = 0; i < _city_number; i++)
_Best_solution[i] = _solution[i];
_Best_length = length;
return;
}
else{
for(int i = t; i < _city_number; i++)//遍历本层的全部结点
{
swap(t, i);
if(OK(t))//约束
{
double L = is_best(t, length);
if(L != -1)//限界
Backtrack(t + 1, L);
}
swap(t, i);
}
}
}
void Print()//输出最优解
{
cout << "以 " << _solution[0] + 1 << " 为出发和结束点最长度为 : " << _Best_length << endl << "路径:" << endl;
for(int i = 0; i < _city_number; i++)
cout << " " << _Best_solution[i] + 1;
}
};
int main()
{
Traveling travel(4);
}
旅行售货商问题----回溯法
最新推荐文章于 2023-11-23 22:15:36 发布