当前位置: 首页 > news >正文

贪心算法之任务选择问题

一、理论推导思路

问题描述:给定n个活动的集合S = {a₁, a₂, ..., aₙ},每个活动a_i有开始时间start[i]和结束时间end[i]。要求选择最多的互不重叠的活动。

贪心策略
每次选择结束时间最早的活动,这样可以为后续活动留下更多时间。具体步骤如下:

  1. 将所有活动按结束时间升序排序
  2. 初始化一个空集合selected,并选择第一个活动(结束时间最早)。
  3. 遍历后续活动,若当前活动的开始时间不早于最后一个选中活动的结束时间,则选中该活动。
二、算法正确性证明

证明方法:交换论证(Exchange Argument)。

假设:存在一个最优解A,其第一个活动的结束时间晚于贪心解的第一个活动a_1的结束时间

步骤

  1. A的第一个活动为a_k,其结束时间end[k] ≥ end[1]
  2. 若将a_k替换为a_1,则新的解 A'的活动数量至少与 A相同(因为a_1的结束时间更早,后续可选活动更多)。
  3. 因此,贪心解a_1是最优解的一部分。
  4. 递归地,剩下的子问题同样满足贪心选择性质,最终得到全局最优解。
三、算法步骤
  1. 输入处理:将活动存储为列表(start, end)
  2. 排序:按活动的end升序排序。
  3. 初始化:选择第一个活动(end最小),记录其结束时间last_end
  4. 遍历选择:从第二个活动开始,若当前活动的start ≥ last_end,则选中该活动,并更新last_end
  5. 输出结果:选中的活动集合。
四、时间复杂度计算
  1. 排序O(n log n)(基于比较的排序)。
  2. 遍历选择O(n)(线性扫描)。
  3. 总时间复杂度O(n log n)
五、实例分析

示例输入
活动列表如下(按原顺序):

活动1: start=1, end=3  
活动2: start=2, end=5  
活动3: start=4, end=7  
活动4: start=6, end=8  
活动5: start=5, end=9  
活动6: start=8, end=10  

步骤解析

  1. 排序后:按end升序排列为活动 1、活动 2、活动 3、活动 4、活动 5、活动 6。
  2. 选择过程
    • 选活动 1(end=3)。
    • 活动 2 的 start=2 < 3 → 跳过。
    • 活动 3 的 start=4 ≥ 3 → 选活动 3(end=7)。
    • 活动 4 的 start=6 < 7 → 跳过。
    • 活动 5 的 start=5 < 7 → 跳过。
    • 活动 6 的 start=8 ≥ 7 → 选活动 6(end=10)。
  3. 结果:选中活动 1、3、6,共 3 个活动。
六、代码示例(Python)
def activity_selection(activities):
    # 按结束时间升序排序
    sorted_activities = sorted(activities, key=lambda x: x[1])
    selected = []
    last_end = -1
    for start, end in sorted_activities:
        if start >= last_end:
            selected.append((start, end))
            last_end = end
    return selected

# 示例输入
activities = [
    (1, 3), (2, 5), (4, 7), (6, 8), (5, 9), (8, 10)
]
selected = activity_selection(activities)
print("选中的活动:", selected)

输出

选中的活动: [(1, 3), (4, 7), (8, 10)]
七、算法总结
  • 贪心策略的有效性:活动选择问题满足贪心选择性质和最优子结构,因此贪心算法能得到全局最优解。
  • 关键步骤:排序和线性扫描,时间复杂度为O(n log n)
  • 应用场景:类似的调度问题(如任务调度、资源分配)可尝试贪心策略,但需验证贪心选择性质。
http://www.dtcms.com/a/113229.html

相关文章:

  • mmap函数的概念和使用方案
  • 爬楼梯问题-动态规划
  • 3536 矩形总面积
  • leetcode4.寻找两个正序数组中的中位数
  • 类 和 对象 的介绍
  • 2024 .11-2025.3 一些新感悟
  • 【33期获取股票数据API接口】如何用Python、Java等五种主流语言实例演示获取股票行情api接口之沪深A股当天逐笔交易数据及接口API说明文档
  • 【2020】【论文笔记】相变材料与超表面——
  • 使用Cusor 生成 Figma UI 设计稿
  • 数据库并发控制问题
  • 麒麟系统桌面版本v10安装教程
  • 【动手学深度学习】卷积神经网络(CNN)入门
  • 低代码开发平台:飞帆画 echarts 柱状图
  • pygame里live2d的使用方法(live2d-py)
  • 人工智能与计算机技术赋能高中教育数字化教学模式的构建与实践
  • Git 分布式版本控制工具
  • 【ROS2】〇、ROS2的安装
  • 神经网络与深度学习:案例与实践——第三章(2)
  • 3D图像重建中Bundle Adjustment的推导与实现
  • Shell脚本笔记
  • Java第三节:新手如何用idea创建java项目
  • #SVA语法滴水穿石# (004)关于 ended 和 triggered 用法
  • Java HttpURLConnection修仙指南:从萌新到HTTP请求大能的渡劫手册
  • #SVA语法滴水穿石# (005)关于 问号表达式(condition ? expr1 : expr2)
  • Arduino示例代码讲解:ADXL3xx 加速传感器
  • Java 类型转换和泛型原理(JVM 层面)
  • 论定制开发开源 AI 智能名片 S2B2C 商城小程序源码在零售变革中的角色与价值
  • 基于sklearn实现文本摘要思考
  • Linux进程间通信——有名管道
  • 【AI论文】基础智能体(Foundation Agents)领域的进展与挑战:从类脑智能到进化型、协作型及安全型系统