#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
typedef struct Point
{
int x;
int y;
}Pt,*pPt;
void sort(pPt pt,int len)
{
for(int i=1;i<len;i++)
{
int j=i-1;
Pt p=pt[i];
while(j>=0 && p.x<pt[j].x)
{
pt[j+1]=pt[j];
j--;
}
pt[j+1]=p;
}
}
void printP(pPt pt,int len)
{
for(int i=0;i<len;i++)
{
printf("{%d,%d}",pt[i].x,pt[i].y);
}
printf("\n");
}
double dist(Pt p1,Pt p2)
{
return sqrt(pow((double)p1.x-(double)p2.x,2)+pow((double)p1.y-(double)p2.y,2));
}
double ** dp(pPt pts,int len,int **b)
{
double **s=(double**)malloc(len*sizeof(double*));
int i,j,k;
for(i=0;i<len;i++)
{
s[i]=(double*)malloc(len*sizeof(double));
}
for(i=0;i<len;i++)
{
for(j=0;j<len;j++)
{
s[i][j]=0.0;
}
}
s[0][1]=s[1][0]=dist(pts[0],pts[1]);
for(i=0;i<len-1;i++)
{
//case i==j:
//s[i][j]=s[i-1][i]+dist(i-1,j);
//exclude s[0][0],leave it 0
if(i>0)
{
s[i][i]=s[i-1][i]+dist(pts[i-1],pts[i]);
b[i][i]=i-1;
}
//case i+1==j:
//s[i][j]=min{s[i][k]+dist(k,j)}(0=<k<j)
double min=DBL_MAX;
j=i+1;
for(k=0;k<j;k++)
{
double m=s[i][k]+dist(pts[k],pts[j]);
if(m<min)
{
min=m;
b[i][j]=k;
}
}
s[i][j]=min;
s[j][i]=s[i][j];
//case j>i+1:
//s[i][j]=s[i][j-1]+dist(j-1,j)
for(j=i+2;j<len;j++)
{
s[i][j]=s[i][j-1]+dist(pts[j-1],pts[j]);
s[j][i]=s[i][j];
b[i][j]=b[j][i]=j-1;
}
}
i=j=len-1;
s[i][j]=s[i-1][i]+dist(pts[i-1],pts[j]);
s[j][i]=s[i][j];
b[i][j]=i-1;
return s;
}
void printS(double **s,int len)
{
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
printf("%.2f ",s[i][j]);
}
printf("\n");
}
printf("\n");
}
void printB(int **b,int len)
{
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
printf("%d ",b[i][j]);
}
printf("\n");
}
printf("\n");
}
void printTrace(int **m,int len)
{
int alen=0,blen=0;
int *a=(int*)malloc(len*sizeof(int));
int *b=(int*)malloc(len*sizeof(int));
//j is always the larger one
int i=len-2;
int j=len-1;
//a begins from len-1,b begins from len-2
a[alen++]=j;
b[blen++]=i;
bool flag=true;//flag==true insert into a,else into b
int t=len-1;
while(t>0)
{
t=m[i][j];
if(flag)
a[alen++]=t;
else
b[blen++]=t;
if(t<i)
{
j=i;
i=t;
flag=!flag;
}
else
{
j=t;
}
}
for(i=0;i<alen;i++)
printf("%d ",a[i]);
for(j=blen-1;j>=0;j--)
printf("%d ",b[j]);
}
void main()
{
int n=7;
Pt p1={2,1};
Pt p2={1,7};
Pt p3={9,3};
Pt p4={6,5};
Pt p5={8,6};
Pt p6={3,4};
Pt p7={7,2};
pPt pts=(pPt)malloc(n*sizeof(Pt));
pts[0]=p1;
pts[1]=p2;
pts[2]=p3;
pts[3]=p4;
pts[4]=p5;
pts[5]=p6;
pts[6]=p7;
sort(pts,n);
//printP(pts,n);
int **b=(int**)malloc(n*sizeof(int*));
int i,j,k;
for(i=0;i<n;i++)
{
b[i]=(int*)malloc(n*sizeof(int));
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
b[i][j]=-1;
}
}
double **s=dp(pts,n,b);
printS(s,n);
printB(b,n);
printTrace(b,n);
getchar();
}
算法道路 思考题 15-3(双调欧几里得旅行商问题)
最新推荐文章于 2020-10-27 16:34:42 发布