单峰函数求极小值问题。。。果断三分法。。。
在ab段找一点m1,在cd段找一点m2,则 t=length(a,m1)/p+length(m1,m2)/r+length(m2,d)/q;
在外层对ab段三分,在内层对cd三分,求最小值。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<float.h>
#define esp 1e-6
//双三分法(两层)求函数极值
struct point
{
double x,y;
}A,B,C,D;
int p,q,r;
double len(struct point a,struct point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double solve1(struct point m) //对CD段三分
{
double t1,t2;
struct point left,right,mid,midmid;
left=C;
right=D;
do{
mid.x=(left.x+right.x)/2;
mid.y=(left.y+right.y)/2;
midmid.x=(mid.x+right.x)/2;
midmid.y=(mid.y+right.y)/2;
t1=len(m,mid)/r+len(mid,D)/q;
t2=len(m,midmid)/r+len(midmid,D)/q;
if(t1<t2) right=midmid;
else left=mid;
}while(fabs(t1-t2)>=esp);
return t1;
}
double solve2() //对AB段三分
{
double t1,t2;
struct point left,right,mid,midmid;
left.x=A.x; left.y=A.y;
right.x=B.x; right.y=B.y;
do{
mid.x=(left.x+right.x)/2;
mid.y=(left.y+right.y)/2;
midmid.x=(mid.x+right.x)/2;
midmid.y=(mid.y+right.y)/2;
t1=len(A,mid)/p+solve1(mid);
t2=len(A,midmid)/p+solve1(midmid);
if(t1<t2) right=midmid; //求解最小值
else left=mid;
}while(fabs(t1-t2)>=esp);
return t1;
}
int main()
{
int t,i,j,k;
scanf("%d",&t);
while(t--){
scanf("%lf %lf %lf %lf",&A.x,&A.y,&B.x,&B.y);
scanf("%lf %lf %lf %lf",&C.x,&C.y,&D.x,&D.y);
scanf("%d %d %d",&p,&q,&r);
printf("%.2lf\n",solve2());
}
//system("pause");
return 0;
}