旅行售货商问题----回溯法

例题

#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);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值