【贪心算法】活动选择问题——算法设计与分析


一、问题定义

输入:

  • n n n个活动组成的集合 S = { a 1 , a 2 , . . . , a n } S={\left \{a_1,a_2,...,a_n \right \} } S={a1,a2,...,an}
  • 每个活动 a i a_i ai的开始时间 s i s_i si和结束时间 f i f_i fi

输出:

  • 找出活动集合 S S S的子集 S ′ S' S,使得 m a x ∣ S ′ ∣ max|S'| maxS,其中 ∀ a i , a j ∈ S ′ , s i ≥ f j \forall a_i,a_j \in S', s_i \ge f_j ai,ajS,sifj s j ≥ f i s_j \ge f_i sjfi


二、贪心求解

2.1 提出贪心策略

通过观察问题特征,构造贪心选择,并通过举反例的方式筛选掉得不到最优解的贪心策略。

在这里插入图片描述


通过举例可以发现,策略3可以得到最优解:

在这里插入图片描述

接下来就是要证明策略3能够保证得到最优解。


2.2 贪心正确性证明

通常可以采用替换法进行证明:

假设存在一个最优方案,不断地等价替换最优方案里的内容(始终保持为最优方案),直至与贪心所得到的结果相同,即可证明贪心解不劣于最优解,也就证明了贪心解可以保证得到最优解。

从前往后依次检查最优解和贪心解,如果活动相同,则无需替换;如果活动不同,则将最优解里的活动替换为贪心解里的活动,此时并不会影响最优解的活动个数。因为在贪心解中优先选择的是先完成的活动,所以替换过去的活动不会晚于原活动结束,替换之后可以为最优解后续的活动提供更大的空间,至少不会影响后续活动,故依然保持最优解。

最终,可以将最优解替换为贪心解,证明了贪心解不劣于最优解,完成证明。


2.3 伪代码

在这里插入图片描述



三、贪心算法总结

3.1 贪心算法的特点

(1)贪心法适用于组合优化问题

(2)求解过程是多步判断过程,最终的判断序列对应于问题的最优解

(3)依据某种“短视的”贪心选择性质判断,在一系列步骤下,每一步有一组选择,作出当前来看最好的选择

(4)贪心法必须进行正确性证明

(5)证明贪心法不正确的技巧:举反例

贪心法的优势:算法简单,时间和空间复杂性低


3.2 适用条件

贪心算法适用条件:

  • 贪心选择性:一个最优问题的全局最优解可以通过局部最优选择得到
  • 问题具有最优子结构:一个最优问题的最优解包含它的子问题的最优解

3.3 贪心正确性证明思路

贪心算法正确性证明:

  1. 证明问题具有贪心选择性(证明最优解中一定包含的第一步,地位相当于数学归纳法的首项)

  2. 证明问题具有最优子结构(证明最优解中去掉第一步后剩下的依然是子问题的最优解;通常使用反证法,假设不是最优解,则存在子问题的别的最优解,加上第一步后,比原问题的最优解还要好,与原问题是最优解产生了矛盾)

  3. 是用数学归纳法对算法正确性进行证明(利用贪心选择性和最优子结构)

上述已经阐述了正确性的证明方法,以下是另一种表述,与上面本质相同,只是上面的使用数学语言更多,更加严谨。

(1)替换法

假设存在一个最优方案,不断地等价替换最优方案里的内容(始终保持为最优方案),直至与贪心所得到的结果相同,即可证明贪心解不劣于最优解,也就证明了贪心解可以保证得到最优解。

(2)数学归纳法

方法:第一归纳法、第二归纳法

证明步骤:

①叙述一个有关自然数 n n n的命题,该命题断定该贪心策略的执行最终将导致最优解。其中自然数 n n n可以代表算法步数或者问题规模

②证明命题对所有的自然数为真。归纳基础:从最小实例规模开始;归纳步骤:第一或第二数学归纳法

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 卫兵布置问题是指在一个 $n\times m$ 的矩阵中,放置若干个卫兵,使得每行和每列都至少有一个卫兵,并且卫兵之间不能相互攻击,即同行、同列或同一对角线上不能有两个及以上的卫兵。求解放置卫兵的方案数。 这个问题可以用搜索算法来解决。我们可以用一个二维数组 $board$ 来表示矩阵,其中 $board_{i,j}=1$ 表示该位置已经放置了卫兵,$board_{i,j}=0$ 表示该位置还没有放置卫兵。我们可以从第一行开始,枚举每个位置放置卫兵或不放置卫兵,然后递归到下一行,直到最后一行。如果在最后一行放置了卫兵,那么我们就找到了一个合法的方案;否则,我们就需要回溯到上一行,重新枚举该行的下一个位置。 具体实现细节可以参考下面的代码: ### 回答2: 卫兵布置问题是一个典型的算法程序设计问题,通常是在一定区域内布置一定数量的卫兵,使得每个区域都能够被卫兵所覆盖。 首先,我们可以采用贪心算法来解决这个问题贪心算法的基本思想是,每次都选择当前情况下最优解,以期望得到全局最优解。 具体实现上,可以按照以下步骤进行: 1. 将要布置的区域按照一定的规则排序,比如按照面积从大到小排序。 2. 选择第一个区域进行布置,将一个卫兵放置在这个区域的中心位置。 3. 从第二个区域开始,遍历每个区域,如果该区域与已布置的卫兵的覆盖区域没有交集,则在该区域的中心位置再放置一个卫兵。 4. 不断循环3,直至所有的区域都被遍历完毕。 贪心算法的时间复杂度为O(nlogn),其中n为区域的个数。该算法保证了每个区域都能够被卫兵覆盖,但并不能保证卫兵的数量最少。 如果需要保证卫兵的数量最少,我们可以使用更复杂的算法,比如动态规划算法。动态规划算法通常包含以下几个步骤: 1. 定义状态:设f(i)表示前i个区域所需要的最少卫兵数量。 2. 初始化状态:f(1)为1,即第一个区域需要一个卫兵。 3. 状态转移方程:f(i) = min{f(j) + 1},其中j < i且第j个区域的覆盖范围可以覆盖第i个区域。 4. 求解最优解:最后返回f(n)即为最终结果。 动态规划算法的时间复杂度为O(n^2),需要使用一个数组来保存中间结果。这种算法能够保证卫兵的数量最少,但相对于贪心算法来说更加复杂一些。 综上所述,卫兵布置问题算法程序设计中可以采用贪心算法或动态规划算法来求解,具体的选择取决于问题的要求和时间复杂度的需求。 ### 回答3: 卫兵布置问题是指如何在给定的一组区域中,安排卫兵的位置,以实现最佳的防御效果。 解决卫兵布置问题算法程序设计可以采用以下步骤: 首先,需要分析给定的区域,了解每个区域的特点和可能的入侵路径。可以将区域抽象为一个二维矩阵,每个位置表示一个区域。 其次,确定卫兵的数量和他们的限制条件。这包括卫兵的总数目、布置的范围以及相邻卫兵之间的最小距离等。 接下来,根据防御策略设计相应的算法。一种常见的算法是贪婪算法,即每次选择一个最优的位置来布置卫兵,直到卫兵数量达到要求或不能再继续放置为止。该算法可以根据区域的特点和入侵路线来选择最佳的位置。另一种常用的算法是回溯算法,通过递归地尝试不同的布置方式,找到最佳的卫兵布置方案。 最后,实现并测试设计好的算法。可以根据给定区域的大小和要求的卫兵数量来生成测试样例,并通过结果验证算法的正确性和有效性。 总之,卫兵布置问题是一种优化问题,需要通过谨慎的分析和设计来找到最佳的解决方案。算法程序设计可以通过贪婪算法、回溯算法等方法来解决此类问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

友人帐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值