1150巡回セールスマン問題(25ポイント)

アイデア:

巡回セールスマン問題、隣接行列を使用して無向右グラフを実現し、指定されたパスに従ってノードにアクセスし、すべてのノードのアクセスに従って、開始ノードを除くリング\単純リング\その他であると判断します。 、他のノードが1回だけ、0回、または2回以上アクセスするかどうか、開始と終了が同じかどうかなど。

1150巡回セールスマン問題(25ポイント)

「巡回セールスマン問題」は、次の質問をします。「都市のリストと都市の各ペア間の距離を考えると、各都市を訪れて元の都市に戻る最短ルートはどれですか?」これは、組み合わせ最適化におけるNP困難な問題であり、オペレーションズリサーチや理論計算機科学において重要です。(「https://en.wikipedia.org/wiki/Travelling_salesman_problem」から引用。)

この問題では、与えられたサイクルのリストから、巡回セールスマン問題の解に最も近いものを見つけることになっています。

例:

#include<iostream>
#include<vector>
using namespace std;

struct Graph {
    int Nv;
    int Ne;
    vector<vector<int>> G;
};

int ShortestDist = -1;
int ShortestPath = -1;

void solve(Graph &G, int path)
{
    int n;
    cin >> n;
    vector<int> Path(n);
    for(int i = 0; i < n; i++) cin >> Path[i];
    string Description = "(TS simple cycle)";
    if(Path[0] != Path[n-1]) Description = "(Not a TS cycle)";
    vector<int> Visited(G.Nv+1, 0);
    int TotalDist = 0;
    int src = 0, adj;
    for(int i = 0; i < n; i++) {
        adj = Path[i];
        Visited[adj]++;
        if(src != 0) {
            if(G.G[src][adj] == 0) {
                TotalDist = -1;
                Description = "(Not a TS cycle)";
                break;
            }
            TotalDist += G.G[src][adj];
        }
        src = adj;
    }
    if(Description == "(TS simple cycle)") {
        for(int i = 1; i <= G.Nv; i++) {
            if((i == Path[0] && Visited[i] > 2) || (i != Path[0] && Visited[i] > 1)) {
                Description = "(TS cycle)";
            } else if(Visited[i] == 0) {
                Description = "(Not a TS cycle)";
                break;
            }
        }
        if((Description != "(Not a TS cycle)") && (ShortestDist == -1 || ShortestDist > TotalDist)) {
            ShortestPath = path;
            ShortestDist = TotalDist;
        }
    }
    cout << "Path " << path << ": ";
    if(TotalDist==-1) cout << "NA";
    else cout << TotalDist;
    cout << " " << Description << endl;
}

int main()
{
    int N, M, K;
    cin >> N >> M;
    Graph G;
    G.Nv = N, G.Ne = M, G.G.resize(N+1);
    for(int i = 1; i <= N; i++) G.G[i].resize(N+1);
    for(int i = 1; i <= M; i++) {
        int c1, c2, dist;
        cin >> c1 >> c2 >> dist;
        G.G[c1][c2] = G.G[c2][c1] = dist;
    }
    cin >> K;
    for(int i = 1; i <= K; i++) solve(G, i);
    cout << "Shortest Dist(" << ShortestPath << ") ";
    cout << "= " << ShortestDist << endl;
}

 

おすすめ

転載: blog.csdn.net/u012571715/article/details/114590144
おすすめ