TSP给出错误输出的算法

时间:2016-04-01 18:07:56

标签: c++ algorithm swap

我花了几个小时试图弄清楚我的计划有什么问题,但我无法弄明白。这是最低旅游费用计划。 (TSP)

c代表城市,a代表弧(2个城市之间的旅行费用)

输入我用来测试:

c 1
c 2
c 3
c 4
c 5
a 1 2 1400
a 1 3 1800
a 1 4 4000
a 1 5 3500
a 2 3 1200
a 2 4 3400
a 2 5 3600
a 3 4 2300
a 3 5 2700
a 4 5 2100

这是我的代码。上面的输入应该给出10500分钟,但它显示5600。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <sstream>
#include <cstdlib>
#include <string>
#include <stdint.h>


using namespace std;



static char gFirstCity = 0;
static unsigned graph[50][50] = {0};
static unsigned minTour = 0xffffffff;


void swap (char *x, char *y)
{
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}
void permute(char* cities, unsigned start, unsigned length)
{
   if (start == (length-1))
   {

       cout << endl;
       unsigned cost =0;


       cost+= graph[(unsigned)gFirstCity][(unsigned)*cities];

       for(unsigned i = 0; i < length-1; i++ )
       {
        cost+=graph[(unsigned)cities[i]][(unsigned)cities[i+1]];
        for(int i = 0; i < length; i++){
            cout << (int)cities[i];
        }
       }
       cost+=graph[(unsigned)cities[length-1]][(unsigned)gFirstCity];
       for(int i = 0; i < length; i++){
           cout << (int)cities[i];
       }
       if(cost<minTour){
           minTour = cost;
       }
   }
   else
   {
        for (unsigned j = start; j < length; j++)
        {
            swap((cities + start), (cities + j));
            permute(cities, start + 1, length);
            swap((cities + start), (cities + j));
        }
    }
}


int main()
{
    string cities;
    string line;
    char command = 0;
    unsigned city = 0;
    while (getline(cin, line))
    {
        sscanf(line.c_str(), "%c %d", &command, &city);
        if (command != 'c')
            break;
        cities.push_back((unsigned char)city);
    }

    gFirstCity = cities[0];

    unsigned to = 0;
    unsigned from = 0;
    uint32_t cost = 0;

    sscanf(line.c_str(), "%c %d %d %d", &command, &to, &from, &cost);
    graph[to-1][from-1]=cost;
    graph[from-1][to-1]=cost;


    while (getline(cin, line))
    {
        sscanf(line.c_str(), "%c %d %d %d", &command, &to, &from, &cost);
        graph[to-1][from-1]=cost;
        graph[from-1][to-1]=cost;
    }


    permute((char*)cities.c_str()+1, 0, cities.length()-1);
    cout << minTour << endl;

    return EXIT_SUCCESS;

1 个答案:

答案 0 :(得分:2)

在代码中添加一些调试输出后,最大的问题似乎是你的算法混合了数组索引和城市不一致。

例如,您的gStartCity用作数组索引(从0开始),但实际上是城市号(从1开始)。

在实际获取成本时使用数组索引1-5,但是将成本分配给数组索引0-4。

我相信您可以通过将两组graph[][]分配更改为:

来获得预期结果
graph[to][from]=cost;
graph[from][to]=cost;

graph[][]的定义将允许这一点而不会覆盖其他内容,并且您将无法长时间使用此算法来计算49个城市的最佳路径,因此差异无关紧要(49个城市会需要大约6E + 62条可能的路径;即使您每秒可以检查一百万条路径,也只需要大约20,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000年来计算。)

你的代码很难阅读和遵循,所以我不确定如何最好地修复你在大多数数组索引上关闭的基本问题,但至少这应该让它更接近于你期待的方式。