博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

算法——穿越沙漠算法

Posted on 2011-08-19 21:11  bug yang  阅读(4987)  评论(0编辑  收藏  举报

一、问题描述

一辆吉普车来到1000km宽的沙漠边沿。吉普车的耗油量为1L/km,总装油量为500L。显然,吉普车必须用自身油箱中的油在沙漠中设几个临时 加油点,否则是通不过沙漠的。假设在沙漠边沿有充足的汽油可供使用,那么吉普车应在哪些地方、建多大的临的加油点,才能以最少的油耗穿过这块沙漠?

二、分析解答

  A-----------Cn---C3---------C2------------------C1--------------------B

起点                                                           临时加油站                    终点

从这个题目来看,这是一个极限问题,求得是最少耗油的量,所以只有唯一答案。

1、从题目来看,为了穿越这个沙漠,同时耗油量最少,那么吉普车就应该每次出发的时候都要满油量出发

2、为了保证每一次都是满油量的从每个临时加油站出发,那么每一个临时加油站的油量储备都应该是500L的倍数。

3、为了保证耗油量最少,每一次建立一个临时加油站的时候,运输的次数也是越少越好,减少重复的路段。

4、如果这道题通过递推法正推的话很难确定第一个临时加油站的地点。

5、所以这里我们用倒推法来做。

6、假设我们已经到达了B点,这个时候B点的储油量应该0,这是可以倒推C1点的储油量应该为500L,这时候可以刚好到达终点B。好了现在我们知道C1点的储油量了,也就知道了C1到B点的距离为500米。

7、这时候我们应该想,如果向C1点运输500L的油量,C2点应该存储多少油呢?根据上面的步骤2(临时加油站的油量储备都应该是500L的倍数)和步骤3(运输的次数也是越少越好,这里肯定是两次或者两次以上才能向C1点运输500L油,这里取2次),那么我们就知道了C2点的储油量应该是500L*2,也就是1000L油。这时,C2到C1的距离为500/3。

8、如果想C2点运输1000L的油,重复步骤7可知,C3点存储油量为500×3L,C3到C2的距离为500/5。

9、所以到达临时加油站Cn的时候,储油量应该是500×n,Cn到Cn-1的距离为500/2n-1。

所以这里通过下面这个式子算出n:

500+500/3+500/5+500/(2n-1) = 1000;

然后就可以得出最少耗油量。

//************************************
// Method: 穿越沙漠问题,最小油耗解法.临时补给站不留油
// Parameter: double dDis,沙漠宽度,两端距离
// Parameter: double speed,单位距离的油耗速度
// Parameter: double oilPer,单次的最大负载
// Returns: void
//************************************
void Travel_Answer(double dDis, double speed, double oilPer)
{
// 满负载可行距离
double disPer = oilPer/speed;
if(dDis <= disPer)
{
printf(
"总距离小于单次满负载可行距离,直接通过即可/n");
return;
}
// 否则需要设置临时补给站,每个临时补给站的储油量应该是单次最大负载的整数倍
double d = disPer;
int i = 1;
while(d < dDis)
{
// 计算下一个补给站
++i;
d
+= 1.0/(2*i-1)*disPer;
}
printf(
"起点需设储油量:%g/n", oilPer*i);
double totalOil = -1;
while(i>1)
{
d
-= disPer/(2*i-1);
--i;
if(totalOil < 0)
{
totalOil
= oilPer*i + (dDis-d)*(2*i+1)/speed;
}
printf(
"下一个补给点为距起点%g处,储油量:%g/n", dDis - d, oilPer*i);
}

printf(
"总耗油量:%g", totalOil);
}

  输出的结果:

起点需设储油量:4000
下一个补给点为距起点22.4331处,储油量:
3500
下一个补给点为距起点60.8947处,储油量:
3000
下一个补给点为距起点106.349处,储油量:
2500
下一个补给点为距起点161.905处,储油量:
2000
下一个补给点为距起点233.333处,储油量:
1500
下一个补给点为距起点333.333处,储油量:
1000
下一个补给点为距起点500处,储油量:
500
总耗油量:
3836.5