greedy策略求解工作选择问题物品质量质量最大化(三)

泄露秘密 提交于 2019-12-26 07:06:34

         该问题求解的是货物谁先生产的问题,由于生产完成的货物存在保质期,已完成的货物每存放一天,货物就会以一个固定的比例decay重量。且每个货物的生产时间都为一天。在所有货物生产完时,求解最终货物的最大重量。

         由于是求解货物重量的最大化,所以该问题本身是一个优化问题,问题的最终目的是得到一个最优解,因此是否能够用greedy优化策略:既然是寻找最后剩余的最大货物质量,那么基于greedy思想,只有每天当前货物的损失最小,就能使最终的货物总重量达到最大。

        由于每过一天货物V都会以比例P损失,而质量越大的货物在同等损失比例下,损失的越多,所以先做质量较小的货物,最后做质量较大的货物,比如最后一个质量最大的货物完成时,就不用存放,不需decay,所以总的损失最小。

       因此,在实现中,问题被简化成了将货物按照重量从小到大进行排序的问题,那么为什么问题最后的实现求解是对货物重量按照从小到大排序呢?是如何找到求解实现该问题的方法呢?其实在对问题进行阅读和分析的过程中,从求解问题的最终目的(最小损失《=》最大剩余总重量)出发,重量越大的物品每放置一天,则以同等比例decay下,其损失越大,所以损失越大的物品越留在后面做,则decay天数越少,则总的损失就越小。那么是不是这样呢?即greedy策略点是不是得到最优解呢?

      本文Greedy策略点是当前decay损失最小,且已完成的货物每天的decay损失最小化。

      本文程序的核心实现是对所有货物的质量进行从小到大的排序,其主体框架程序如下:

double GreedyStrategy::goodsLossMin(vector<double>num)
{
	double sum_value;
	double result=0;
	mergeSortGoods(num, 0, num.size() - 1);
	int t = num.size()-1;
	int day;
	for (int i = 0; i < num.size();i++)
	{
		day = t - i;                             //这里的decay有两种方法:time 和spaces//先以time计算
		result += computerSurplus(num[i], day, 0.2);   //递归中开辟内存的时间与直接用for的时间的比较???
	}
	return result;
}

        上面采用了一个归并排序函数对货物重量进行排序,然后调用了一个计算decay损失剩余函数对已排序的物品进行decay计算,这两个函数的实现如下:


void GreedyStrategy::mergeSortGoods(vector<double>&num, int low, int high)
{
	if (low<high)
	{
		int mid = (low + high) / 2;
		mergeSortGoods(num, low, mid);
		mergeSortGoods(num, mid + 1, high);
		conquerGoods(num, low, mid, high);
	}
}

void GreedyStrategy::conquerGoods(vector<double>&num, int low, int mid, int high)
{
	int i = low;
	int j = mid + 1;
	vector<double>numC;

	while (i <= mid&&j <= high)
	{
		if (num[i]<num[j])
		{
			numC.push_back(num[i]);                      //由小到大进行排序
			i++;
		} 
		else
		{
			numC.push_back(num[j]);
			j++;
		}
	}

	while (i<=mid)
	{
		numC.push_back(num[i]);                      //由小到大进行排序
		i++;
	}

	while (j<=high)
	{
		numC.push_back(num[j]);
		j++;
	}

	for (int i = low, k = 0; i <= high, k < numC.size(); i++, k++)
	{
		num[i] = numC[k];
	}
}

double GreedyStrategy::computerSurplus(double volume, int day,double rate)
{
	while (day)
	{
		volume = volume - volume*rate;
		day--;
	}

	return volume;
}

      总结:根据问题的最终目的进行分析,寻找求解问题的高效算法,若是寻找最优解,则可根据求解目标寻找greedy策略点。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!