贪心法小结

很多情况下局部最优解合起来不一定构成整体最优解(除非满足最优子结构性质)。所以使用贪心法必须证明其可行性,具体就是证明两个性质:

  • 贪心选择性质:使用数学归纳法证明->先考虑问题的一个整体最优解,并证明可以修改这个最优解,使其从贪心选择开始(第一步的选择就要体现贪心),在做出贪心选择后原问题转化为规模较小的类似问题,通过每一步的贪心选择,最后可得到问题的整体最优解
  • 最优子结构性质:使用反证法证明->先假设由问题的最优解导出的子问题的解不是最优的,然后证明在这个假设下可以构造出比原问题的最优解更好的解,从而导致矛盾

    此外需要注意的是,每次做出贪心选择后,都会做出调整!!
    以活动安排为例:n个活动共享一个资源,求解能安排下的活动时间不重叠的最多活动个数->贪心策略:将所有活动按结束时间排序,每次选取使剩余时间最长的活动
    在这里插入图片描述
#include<iostream>
#include<algorithm>
using namespace std;

//贪心法求解活动安排问题
struct Action
{
	int begin;
	int end;
	bool operator<(const Action& e) const   //重载<运算符号 
	{
		return e.end>=end;
	}
};

bool choose[12]={0};

solve(Action Actions[],int n)
{
	//输入排序后的结构体数组,n代表数组长度,0号位置不使用
	int preEnd=Actions[1].end;
	choose[1]=1;
	for(int i=2;i<n;i++)
	{
		if(Actions[i].begin>=preEnd)
		{
			preEnd=Actions[i].end;                                  //每次贪心选择后,都会有对应的调整更新
			choose[i]=1;	
		}	
	} 
	 
}

int main()
{
	Action Actions[]={{0,0},{5,7},{3,8},{1,4},{3,5},{0,6},{5,9},{8,11},{6,10},{2,13},{8,12},{12,15}};
	sort(Actions+1,Actions+11);
	
	solve(Actions,12);
	for(int i=1;i<12;i++)
		cout<<Actions[i].end<<" "; 
		
	cout<<"\n";
	for(int i=0;i<12;i++)
	{
		if(choose[i]==1)
		{
			cout<<i<<" ";
		}
	}
	return 0;
}




证明
1.贪心选择证明

证明贪心选择的正确性实际只需证明:总是存在以 该贪心策略选取的以第一个解 开始的最优解??;eg.设X是问题A的最优解,X=X’+{1},这里需要证明总是存在以活动1开始的最优解
证明如下:若果第一个选中的活动为k(k≠1),可以构造另一个最优解Y,Y中的活动是兼容的,Y与X的活动数相同。那么用活动1取代活动k得到Y’,因为e1≤ek,所以Y’中的活动是兼容的,即Y’也是最优的,所以总存在一个以活动1开始的最优解
以上证明了第一个贪心选择可导致问题的整体最优解(这样便证明了贪心策略的正确性,进而可以等到规模更小的子问题,继续贪心)

2.最优子结构证明

最优子结构需要证明:若X是问题A的最优解,X=X’+{1},则X’是问题A’的最优解(A’={i ∈ \in A|ei≥b1},注意A’的约束条件,这样子问题的解才能与活动1兼容!!)
反证如下:如果能够找到一个A’含有比X’更多活动的解Y’,则将活动1加入Y‘后就得到一个包含比X跟多活动的解Y,这就与X是最优解的假设矛盾,所以X’是子问题A’的最优解

还是没弄太懂,到底该如何表述贪心选择性质和最优子结构性质的关系???? 参考:https://www.jianshu.com/p/5589a313d33e https://www.cnblogs.com/Gavin_Liu/archive/2011/04/10/2011108.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值