【算法设计与分析】贪心法正确性的证明

要证明的是贪心选择性质最优子结构性质

证明步骤

1. 问题形式化描述
  • 理解问题:首先,你需要完全理解问题的要求和限制条件。
  • 定义贪心策略:确定一个贪心策略,即在每一步选择中,你将如何做出局部最优的选择。
2. 证明贪心选择性质
  • 局部最优导致全局最优:证明如果我们总是选择当前看起来最优的选择,那么最终得到的解也是全局最优的。不会出现这个选择不出现在最终答案的情况。
  • 数学归纳法:经常使用数学归纳法来证明贪心选择性质,即证明每一步的贪心选择能够导致问题的一个更小实例的最优解。
3. 证明最优子结构性质
  • 子问题的存在:证明原问题的最优解包含子问题的最优解。
  • 构建子问题:展示如何从原问题的最优解中提取出子问题的最优解。

eg1 活动安排问题

在这里插入图片描述

贪心选择性质

需证明:如果我们总是选择结束时间最早的活动,那么这个选择至少会出现在某个全局最优解中。

感性理解:这样可以尽可能早地释放会议室,为后续的活动提供空间。

证明:假设已经有一个最优的活动集合A,其中包含了活动a1, a2, …, ak,并且这些活动的结束时间是按非递减顺序排列的。如果我们将第一个活动(结束时间最早的活动)替换为活动1(所有活动中结束时间最早的活动),这个新集合A’仍然会是一个相容的活动集合,并且不会比原来的集合A差。因此,我们可以得出结论,结束时间最早的活动至少会被包含在某个最优解中。

最优子结构性质

需证明:如果我们已经安排了结束时间最早的活动,那么剩下的问题(即安排剩下的活动)仍然是一个活动安排问题,其最优解也将是原问题的一个最优解。

证明:假设我们有一个最优的活动集合A,并且我们已经安排了结束时间最早的活动1。如果我们从集合P中删除活动1以及与其冲突的活动,我们得到一个新的活动子集P’。在P’中,我们可以安排的活动集合就是A中除了活动1之外的其他活动。这个子集也是P’的最优活动集合,因为如果我们在P’中安排更多的活动,那么加上活动1后,安排的活动数就会超过A,这与A是最优活动集合的假设相矛盾。

eg2 哈夫曼编码问题

贪心选择性质:

  1. 对于任何最优编码树,每个叶子节点都有兄弟节点。 如果某个叶子节点没有兄弟节点,那么将其取代其父节点可以得到一个更优的编码树。
  2. 对于任何最优编码树,频率最小的两个字符 (a_1) 和 (a_2) 必须作为兄弟节点结合在一起,并位于树的最底层。 如果不是这样,通过将它们调整到最下层可以达成更优的编码树。

最优子结构性质:

  1. 基础情况:对于 (n=1, 2, 3) 的情况,可以直接验证哈夫曼树是最优的。

  2. 归纳假设:假设对于 (n = k-1) 个字符,哈夫曼树的最优性成立。

  3. 归纳步骤:考虑 (n = k) 个字符的情况。假设存在一棵最优编码树 (A),但它不遵循哈夫曼树的原则(即不总是合并最小的两个节点)。根据引理,(a_1) 和 (a_2) 必须位于树的最下层。

    • 构建虚拟节点:将 (a_1) 和 (a_2) 合并成一个虚拟的叶子节点 (v),得到树 (A’)。树 (A’) 的总编码长度等于树 (A) 的总编码长度减去 (a_1 + a_2)(原因:两兄弟合并到了父节点上。假设根到该父节点的距离是e,原来是a1(e+1)+a2(e+1),合并后是(a1+a2)e,整体少了到a1和a2两个叶子的长度=1的边)
    • 哈夫曼树的对应:在哈夫曼树 (H) 中,也存在一个虚拟节点 (v),它是 (a_1) 和 (a_2) 合并的结果。构建树 (H’),其总编码长度等于 (H) 的总编码长度减去 (a_1 + a_2)。
  4. 比较和矛盾

    • 如果树 (A) 优于哈夫曼树 (H),那么树 (A’) 也应优于树 (H’)。
    • 但是,对于节点 (v)、(a_3) 到 (a_k),根据 (n = k-1) 的归纳假设,(H’) 是最优的。这导致矛盾,因为我们假设 (A’) 优于 (H’),但实际上 (H’) 是最优的。

注:

  • A’和H’指的是深度n=k-1时的树,A和H是n=k的树
  • 最优编码不一定是按照哈夫曼算法得到的,但它只能做到和哈夫曼一样优,不能超过哈夫曼。

eg3 单源最短路-dij算法

贪心策略:在Dijkstra算法的每一步中,从集合 ( V-S ) 中选择具有最短特殊路径长度 ( dist[u] ) 的顶点 ( u ),将其加入到集合 ( S ) 中

贪心选择性质

需证明:对于任意已经在集合S中的顶点u,从源点v开始、经过图中任意顶点到达u的全局最短路径的长度d(v, u)等于从v开始、只经过集合S中顶点到达u的最短路径长度dist(u)。

反证法:

假设存在另一条v到u的最短路径,该路径上某些节点x不在S 中,且该路径长度 d(v,u)<dist[u]

为方便表述,假设从v到u的全局最短路径上,经过的第1个不属于S的顶点为x


(上图)由“v到u的最短路径经过x”,意思就是红线总长比绿线短。
在这里插入图片描述
(上图)那么去掉一段,红线就更短了。

如此一来产生矛盾:若红线比绿线更短,那么x应该是比u先加入到集合S中,怎么还会在集合之外呢?

所以,最初假设不成立。

最优子结构性质

需证明:添加u到S中后,重新计算全部顶点的dist,均不增加。

全部顶点分为三类:

  • 集合S中的顶点(除u)
  • 集合外的顶点i
  • 新加入S的u

S中全部顶点的dist都不会再变了,这是贪心选择性。故只需讨论集合外的顶点i。

(下图)红线长度是旧dist[i]值,算法是:如果绿线长度小于红线,那么更新dist[i]。所以dist值只会变小不会变大。
在这里插入图片描述

eg4 prim算法

从任意一个顶点开始,逐步扩展最小生成树,直到包含所有顶点。

贪心选择

  1. 我们从一个顶点开始,比如叫它a。我们找到与a相连的边中权重最小的边,这条边连接了a和另一个顶点b,我们把这条边叫做y。
  2. 我们证明这条边y是所有最小生成树中的一条边。假设我们已经有了一个最小生成树G,如果y已经在G中,那我们就没什么好说的,Prim算法显然是正确的。
  3. 如果y不在G中,我们把y加进去,这时候会形成一个环。在这个环中,除了y以外的边都是连接在最小生成树中的,所以我们可以从环中移除任何一条与a相连的边c。这样我们得到了一个新的生成树G’。
  4. 因为y是我们能找到的连接a和b的最小边,所以它的权重肯定小于或等于边c的权重。这意味着G’的总权重不会超过G的总权重,所以G’也是一个最小生成树。这样,我们就证明了Prim算法每次选择的边都是正确的。

最优子结构

  1. 我们假设Prim算法得到的最小生成树是G,我们找到G中权重最小的两条边,它们连接了两个顶点a和b,我们把这两条边中的一条叫做y。
  2. 我们把a和b合并成一个新顶点c,删除边y,得到一个新的树G’。如果G’是最小生成树,那么原问题的正确性就得到了证明。
  3. 如果G’不是最小生成树,那么一定存在另一个最小生成树G’‘,它的总权重小于G’。但是,因为我们在合并a和b时,只考虑了连接它们的最小边,所以任何比G’更小的生成树都必须包含边y。
  4. 这意味着,如果我们把G’‘中的顶点c重新拆分成a和b,并且把边y加回去,我们得到的新树G’‘‘的总权重仍然小于G。但这与G是最小生成树的事实矛盾,因为G’’'至少和G一样好,但又包含了更多的边。
  5. 因此,我们的假设不成立,G’必须是最小生成树,这证明了Prim算法的正确性。

eg5 Kruskal算法

按边的权重从小到大排序,然后逐个考虑这些边,如果加入这条边不会形成环,就把它加入最小生成树。

贪心选择

  1. 我们假设Kruskal算法得到的树是G。我们考虑一个最小生成树T,如果G和T是一样的,那么问题的正确性就得到了证明。
  2. 如果G和T不一样,那么G中至少有一条最小权值的边在T中不在。我们把这条边叫做e。
  3. 我们把e加到T中,这会形成一个环。在这个环中,我们找到一条不在G中的边f,并且移除它,得到新的树T’。
  4. 如果f的权重大于e,那么T’的总权重就会小于T,这与T是最小生成树的事实矛盾。
  5. 如果f的权重小于e,那么在Kruskal算法中,我们会选择f而不是e,因为f会先被考虑。这意味着在T中,会和f形成环的边的权重都不会超过f,所以它们都不会被选入G。
  6. 因此,我们只能得出f的权重等于e的结论,这意味着T’仍然是最小生成树,而且T’和G有更多相同的边。这样,我们就证明了Kruskal算法每次选择的边都是正确的。

最优子结构

  1. 我们假设Kruskal算法得到的最小生成树是G,我们找到G中权重最小的边e,把它连接的两个顶点a和b合并成一个新的顶点c,删除边e,得到新的树G’。
  2. 如果G’是最小生成树,那么原问题的正确性就得到了证明。
  3. 如果G’不是最小生成树,那么一定存在另一个最小生成树G’‘,它的总权重小于G’。
  4. 但是,因为我们在合并a和b时,只考虑了连接它们的最小边,所以任何比G’更小的生成树都必须包含边e。
  5. 这意味着,如果我们把G’‘中的顶点c重新拆分成a和b,并且把边e加回去,我们得到的新树G’‘‘的总权重仍然小于G。但这与G是最小生成树的事实矛盾,因为G’’'至少和G一样好,但又包含了更多的边。
  6. 因此,我们的假设不成立,G’必须是最小生成树,这证明了Kruskal算法的正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值