#include <iostream>
#include <cmath>
#include <fstream>
using namespace std;
#define N 7
struct Point{
double x;
double y;
};
struct Point points[N+1];
double b[N+1][N+1];
int r[N+1][N+1];
double distance(int i,int j);//第i,j点的欧式距离
double Euclidean_TSP();//最短闭合旅程长度
void my_print_path();//打印旅程
void main(int argc, char **argv){
ifstream infile;
infile.open("input.txt");//读入一个有各点坐标的文档
if (!infile)
{
cout<<"error!"<<endl;
}
int i=1;
while (infile>>points[i].x>>points[i].y)
{
i++;
}
cout<<"最短双调闭合旅程长度是:"<<Euclidean_TSP()<<endl;
my_print_path();
}
double distance(int i,int j){
return sqrt((points[i].x-points[j].x)*(points[i].x-points[j].x)
+(points[i].y-points[j].y)*(points[i].y-points[j].y));
}
double Euclidean_TSP(){
b[1][2]=distance(1,2);//最小的子问题
for (int j=3;j<=N;j++)
{
//i<j-1且i>=1时的情况
for (int i=1;i<j-1;i++)
{
b[i][j] = b[i][j-1]+distance(j-1,j);
r[i][j] = j-1;
}
//i=j-1的情况
b[j-1][j] = b[1][j-1]+distance(1,j);//先设初值为k=1时的值
r[j-1][j] = 1;
for (int k=1;k<j-1;k++)
{
double q = b[k][j-1]+distance(k,j);
if (q < b[j-1][j])
{
b[j-1][j] = q;
r[j-1][j] = k;
}
}
}
b[N][N] = b[N-1][N]+distance(N-1,N);
return b[N][N];
}
void my_print_path(){
int string[N];
string[0]=N;
string[1]=N-1;
int k=N-1;
int left_hand=N-1,right_hand=N,begin=2,end=N-1;
for (int i=N-1,j=N;k!=1;)
{
k=r[i][j];
if (left_hand>right_hand) //比较那边的点的序号大
{
left_hand=k;
string[begin]=k;
begin++;
}else{
right_hand=k;
string[end]=k;
end--;
}
if (i==j-1)
{
j=i;
i=k;
}else if (i<j-1)
{
j=k;
}
}
cout<<"该旅程是:";
for (int index=0;index<N;index++)
{
cout<<string[index];
}
cout<<endl;
}
算法导论答案 思考题15-1 双欧几里德旅行商问题
最新推荐文章于 2021-02-27 20:55:27 发布