将最优装载问题的贪心算法推广到2艘船的情形,贪心算法仍能产生最优解吗?

算法分析第五次讨论马上就要到了,我搜索了一下讨论的第一道题目,发现竟然没有详细的解释,我就知道我的机会来了,这下要你们这些喜欢上网搜答案的小崽子们尝尝我的厉害。


开个玩笑,还是开始传教吧。

翻了一下习题解答,它说见主教材第5章的装载问题。

......喵喵喵,裤子都脱了,你就给我看这个?

说实话其实这个还是有用的,第五章就讲了两艘船的装载问题,他用的是回溯法,因为贪心算法已经不能得到问题的最优解了,所以选择用回溯法来做。其实第五章的问题已经发生了稍许变化,它的要求变成了,是否有一个合理的装载方案,将这n个集装箱装上这2艘船。但我们这个题目说的是将一艘推广到两艘,所以我们就根据一艘的要求来做。一艘的要求是装尽可能多的箱子。

那为什么最优装载问题的贪心算法,不能推广到两艘船的情形?

因为两艘船的装载问题,是先装完第一艘,再装第二艘,所以就必须把第一艘尽可能的装满,才能使总的装载量更多。如果使用贪心算法求解,第一艘船装载的方式只可能有一种最优解,就是装载的物品都是以从轻到重的顺序装载,所能装的最大重量,那么问题就来了,从轻到重这样装,不一定是最满的。比如{10,20},c1=20,根据贪心算法,它首先装个10上去,然后,就没然后了,就这样结束了,所以它就没有满足尽可能的装满这一条件 。

#include 
#include
using namespace std;

void Loading(int x[], int w[], int c, int n){
	sort(w,w+n);
	for(int i=1;i<=n;i++)
		x[i]=0;		
	for(int i=0;i<=n&&w[i]<=c;i++){
		x[i] = 1;
		c-=w[i];
	}
}

void Loading2(int x[], int w[], int c1, int c2, int n){
	sort(w,w+n);
	for(int i=1;i<=n;i++)
		x[i]=0;
	int i;
	for(i=0;i<=n&&w[i]<=c1;i++){
		x[i] = 1;
		c1-=w[i];
	}
	for(;i

如上面的代码,6个元素的数组{30,30,30,50,50,60},容量 C1=100,C2=150.箱子总重量为250,轮船的总容量也为250,按理说最优解应该是所有的箱子都能装上船,

但如果使用贪心算法,会先把30,30,30装到第一艘船,就造成了,10个空间的浪费,导致,会有一个箱子不能装上船。

扫描二维码关注公众号,回复: 920244 查看本文章

这也算是反例证明了吧。


为什么要先装第一艘,再装第二艘?

为什么要把第一艘船尽可能的装满?

1,是不是有人想说,怎么不两艘轮流着装,我请你吃个棒槌,你见过轮船轮着装集装箱么?就算你不怕麻烦,两艘轮着装,造成的容量浪费可能更加严重。因为贪心算法是从轻到重,那么最坏的情况就是,下一个要装的集装箱刚好大于轮船的剩余容量。如果是一艘船先装,那第一艘的最后一个箱子算中等大小,那第二艘就是终极大小了,比起两艘船一起装所剩的两个终极大箱子的情况要好太多了。加上贪心算法不能推广到两艘船,所以不能用这种方法。

2,先把第一艘船尽可能的装满,是为了第二艘船能放下更多的箱子。


以上纯属个人思考,有误或是写的不好的地方还请指正。

关于两艘船的最优装载问题的回溯法怎么做,这里就先不说了,因为我也不会。





猜你喜欢

转载自blog.csdn.net/qq_30501975/article/details/70197553