火车运煤问题

来源:互联网 发布:lookalike算法 编辑:程序博客网 时间:2024/04/29 13:15

昨天面试被问到一道面试题,遗憾没有给出最优解。现列如下,给以后面试的同学个参考。

煤矿有 3000 吨煤要拿到距离为 1000 km 的市场上卖,有一辆火车可以用来运煤,火车最多能装 1000 吨煤,且火车本身需要烧煤做动力,每走 1 公里消耗 1 吨煤,如何运煤才能使得运到市场的煤最多,最多是多少?



图1 示意图

先说说当时我的思路:

1.因为路途比较远,故中途必然可以允许放置煤,且可以再次回到出发点。

2.第一次出发,拉 1000 吨,跑 250 公里,将 500 吨煤放下(记为 M1),然后返回到 A;

3.第二次出发,拉 1000 吨,跑到 250 公里时,从 M1 处取 250 吨煤,刚好弥补用掉的 250 吨煤,再跑 250 公里。放置 500 吨,记为 M2,然后返回。到 M1 处时,取剩下的 250 吨

煤,刚好回到 A;

4.第三次出发,拉 1000 吨,跑到 M2 时,取回剩下的 500 吨,刚好弥补用掉的 500 吨,跑到 B 时,还剩下 500 吨。

因此,最后可以剩下 500 吨。


当时,面试官说这不是最优的解,我又想了一会,还是想不出更好的解。后来面试官就问别的了(最后面试官还是让我过了)。这里插一句,面试时,对于一个问题就算你当时回答不上来,也不用紧张,面试官并不是想难住你,而是从各方面考察你。对于一两个问题你答不上来,其实后果并不会很严重,他可能会转而问其他的问题,争取多了解你,知道你的长处,你的短处。一般来讲,答到 80% 的问题就很不错了。

后来回来再认真想了一下,想出了最优解。其实这题去分析细节会很麻烦。你可能会有这些疑问,火车应该来回多少趟?火车每次经过一个临时储煤点的时候,应该从里面取多少煤合适?诸如此类细节麻烦的问题!下面给出一种思路,只需要从总量上考虑即可。

思路:

1.首先,火车必然要折返,回到 A 点,也即,他肯定会从 A 出发两次或以上。下面分情况讨论。

2.设火车从 A 出发两次,则中途有一个储煤点。作图如下:


图2 出发两次

箭头线表示火车行驶路线,数字表示时序。

很明显,要达到最优解,得满足两个条件:

1.火车在离开储煤点(设为 M)时有最大可能的煤(1000 吨)

2.M 尽量远。

设 M 距 A 为 x 吨煤跑的距离,1000 - 2 * x 为火车在 M 处储下的煤的数量。1000 - x 为第二次出发,到 M 时煤的数量。在 M 时,火车将煤装上,总数为 1000 - 2x + 1000 - x = 2000 - 3x 公里的煤,此时,火车已经跑了 x 公里,还需要 1000 - x 公里的煤。于是,我们求 (2000 - 3x) - (1000 - x) 的最大值即可。

先求 x 的取值范围:(0,500),即火车最多跑 500 公里远(此时,在 M 处放置 0 吨煤,因此是开区间)。

第二次出发,经过 M 时,总煤为 2000 - 3x ,但火车最多只能装 1000,所以 2000 - 3x <= 1000 即 x >= 333

综上,x 取值范围为 [333,500]

(2000 - 3x) - (1000 - x) = 1000 - 2x。故最大值为 1000 - 2 * 333 = 334。

其实也不用这么计算,这样太麻烦了。可以这样想,火车在离开储煤点时,必然是满载才是最划算的。这里你可能要争辩,如果储煤点不能满足火车满载,但是储煤点比较远,是否也能达到最优解呢。画图示意:


图 3 哪种更优

答案是,方案 1 更优,也即能提供满载的更优。可以这样解释:方案 2 可以看作是方案 1 中的火车继续往前开到一个点,然后放下一定的煤。设 Y = M2 - M1,很明显,火车为了多跑 Y 路程,付出了双倍的煤(去,来)。如果把这 Y 路程留给下次火车去跑,则他只用付出一次 Y 的煤,所以多跑 Y 其实是不划算的,即,提供满载方案必定是最优的。

因此,图 2 的情况可以这样计算:火车离开储煤点时,应该满载,故 2000 - 3x = 1000;故 x = 1000 / 3,故可以剩下 1000 - (1000 - 1000 /3) = 1000 * (1/3)(也即原解法的 334,因为中间有近似计算)。


上面讨论的是从 A 出发两次,且中途只有一个储煤点,如果从 A 出发三次,且中途有两个储煤点。作图如下:


图4 出发三次

由上面红色字体所描述的,每次火车经过 M1 向 B 开进时都满载,且每次经过 M1 向 A 开进时都空,且装载的煤刚好够火车开回到 A;每次火车经过 M2 向 B 开进时都满载,且经过 M2 向 A 开进时都空,且在 M2 装载的煤刚好够开到 上一个储煤点 M1。

如此,便能达到最优解。设 A 距 M1 为 x,M1 距 M2 为 y,因此可以很方便地列出式子:

1000 = 5 * x

1000 = 3 * y

剩余的煤为:1000 - (1000 - (x + y)) = x + y。计算结果为 1000 * (1/3 + 1/5) = 533.3 吨。


综合前面的看来,有如下的规律,设中途有 n 个储煤点,则最优的解为:

1000 * (1/3 + 1/5 + ...... + 1/(n + 2)),很明显,中途储煤点越多,则最优解值越大。

但是,每回去一趟,都要取 1000 吨煤,题目给定煤只有 3000 吨煤,所以只能回去三次,即只能有两个中途储煤点,即最后的最优结果为 533.3 吨。








0 0
原创粉丝点击