1. 程式人生 > >演算法設計與分析: 3-15 雙調旅行售貨員問題

演算法設計與分析: 3-15 雙調旅行售貨員問題

3-15 雙調旅行售貨員問題

問題描述

歐氏旅行售貨員問題是對給定的平面上 n 個點確定一條連線這 n 個點的長度最短的哈密 頓迴路。由於歐氏距離滿足三角不等式,所以歐氏旅行售貨員問題是一個特殊的具有三角不 等式性質的旅行售貨員問題。它仍是一個 NP 完全問題。最短雙調 TSP 迴路是歐氏旅行售貨 員問題的特殊情況。平面上 n 個點的雙調 TSP 迴路是從最左點開始,嚴格地由左至右直到 最右點,然後嚴格地由右至左直至最左點,且連線每一個點恰好一次的一條閉合迴路。

給定平面上 n 個點,程式設計計算這 n 個點的最短雙調 TSP 迴路。

資料輸入:
第 1 行有 1 個正整數 n,表示給定的平面上的點數。接下來的 n 行中,每行 2 個實數,分別表示點的 x 座標和 y 座標。

Java

import java.util.*;

class Point{
    int x;
    int y;
}

public class ShuangDiaoLvXingShouHuoYuan {

    private static List<Point> points = new ArrayList<>();
    private static double[] s,t;
    private static int n;

    public static void main(String[] args){
        Scanner input = new
Scanner(System.in); while (true){ points.clear(); n = input.nextInt(); s = new double[n+1]; t = new double[n+1]; for(int i=0; i<n; i++){ Point point = new Point(); point.x = input.nextInt(); point.y = input.nextInt(); points.add(point); } Collections.sort(points, xComparator);//按x座標從小到大排序
dynamic(); System.out.println(String.format("%.2f", t[n])); } } private static Comparator<Point> xComparator = new Comparator<>() { @Override public int compare(Point c1, Point c2) { int result = Integer.compare(c1.x, c2.x); return result; } }; /* t[i]: 點集{p1,p2,...,pi}的最短雙調TSP迴路的長度 */ private static void dynamic(){ s[1] = 0; for(int i=2; i<=n; i++) s[i] = dist(i-1, i) + s[i-1]; t[2] = 2*s[2]; for(int i=3; i<=n; i++){ t[i] = t[2]+s[i]-2*s[2]+dist(i,1); for(int j=2; j<=i-2; j++){ double temp = t[j+1]+s[i]+s[j]-2*s[j+1]+dist(i,j); if(t[i] > temp) t[i] = temp; } } } private static double dist(int p, int q){ return Math.sqrt(Math.pow(points.get(p-1).x-points.get(q-1).x, 2)+Math.pow(points.get(p-1).y-points.get(q-1).y, 2)); } }

Input & Output

7
0 6
1 0
2 3
5 4
6 1
8 2
7 5
25.58

王曉東《計算機演算法設計與分析》(第3版)P94