`
liyiwen007
  • 浏览: 108193 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

《算法导论》笔记--动态规划解活动选择问题

阅读更多

  假设某大学有一个活动室,我是这个活动管理员。某天,有6个社团都提出了使用活动室的要求,并告知了他们希望使用活动室的时间段(他们之间相互不知道对方的要求,因此时间安排是没有相互商量过的,可能有重叠)。活动室不能同时被两个以上社团使用。作为管理员,我无法每次都满足所有人的要求,但我想尽量提高活动室的使用率,那么,我如何选取某几项活动,使得活动室的使用时间最长呢?

活动列表

  如上图,假设上图是某一次这些社团的要求(假设0是正午12点),各颜色条分别是各个社团的使用时间计划。那么,我应该如何分配活动室呢?显然,如果给了社团5,其它社团就不能再使用该活动室了,这时活动室的使用时间是从2点到8点,共使用了6个小时。但这不是最长的使用时间组合。如果将活动室分配给1、3、4、6,那么除了4点到5点之间活动室是空的之外,其它时间活动室都被使用了,一共使用时间是8个小时。

(其实在《算法导论》一书的第16章第一节中,也提到一个活动选择问题。这里说的活动选择问题与书中的不一样。这两个问题要求不一样。那个问题将在贪婪算法相关的内容中讨论)

 

  使用蛮力法,不会是一种好的方法。这一点就不过多论证了。

 

  这是个最优化问题。我们探索下,会发现这个问题的最优解,是有可能表示成子问题最优解的递归解的。假设Tij是一个从i点到j点的时间段,这个时间段内,最长的使用时间是Sij。Sij的计算中用到的活动,必须是要求整个活动时间被包括在Tij中的,不能越过这个时间限。我们就称Vij是这样一个集合,其中包含了所有时间范围被完全包含在Tij范围内的活动。

假设对于i点到j点Tij,如果i=j,那么很显然Sij就是0。如果i不等于j,那么最长使用使用时间Sij可能是j-i个小时,也就是有一个活动从i点一直搞到j点,那么挺好,就选择这个活动就行了。但如果不存在这么长时间的活动,那么,我们可以试着把这个时间分成两个部分Tik和Tkj,它们分别最长的使用时间是Sik和Skj。令S'=Sik+Skj,我们知道,当k从i到j依次取值时,可以得到各组不同的Sik和SkjSij肯定是S'中取最大的那个值。为什么呢?因为如果没有一个在Tij时间内段的活动能充满整个Tij时间段的话,那么Vij内的任何一个活动单独放到Tij时间段内,那么在这个时间段的前端和后端,至少会出现一个空白的没被使用的时间,如下图:

区间内的活动

  所以,直感上看,就可以把空白的时间段取出来,看这个时间段内还能不能再按排一些活动。只要没有一个活动可以填满整个时间段,那么最大使用时间就是Vij内多个活动时间拼接成的。那么对于从i到j内的每一个时间点k,这个点左右两边Tik和Tkj内会分别安排一些活动(因为每个活动都是从整点开始到整点结束,而且各活动使用活动室的时间也不能重叠。但可能Vik或Vkj会为空),就分别能得到Sik和Skj。只要对每一个可能的k值进行检查,那么最大时间肯定就是其中的一个。

因此,我们可以得出Sij的计算方法:

  1. 如果i=j,则 Sij=0
  2. 否则,如果存在一个活动的时候长度恰好为Tij则Sij=j-i
  3. 否则,Sij=max{Sik+Sij} ,其中、k从i到j依次取值。

 

  现在,我们已经得到了这个问题最优解的一个递归形式的解。递归式中包含了子问题的最优解。(关于子问题是否是最优解,可以用《算法导论》中的"剪切粘贴法"来考虑)。这是能用动态规划来解决的问题的第一个特征。

然后再看,如果我们根据这个递归直接翻译写出递归程序,那么,对于会出现很多重复的计算。比如,当我们计算S09时,会用到S01、S02、S03、S04、......、S07、S08,再计算S08时,又会用到S01、S02、S03、S04、......、S07以此类推,这个表达式中存在非常多的重复计算,计算量很大。嗯,有很多重叠的子问题,这是能用动态规划来解决的问题的第二个特征。

  那么,根据动态规划的方法,就应该用从底向上的方法来解决这个问题,先计算小区间的值,并存储起来,然后再利用已经得到的小区间的值来计算大区间的值。最终得到原问题的最优解。如下图 

动态表

  格子[i,j]表示从i点到j点,最大利用时间值是多少。灰掉的部分是无效值,因为此时i值大于j值,没有实际意思。这个表,我们从左到右计算每一列的值,就是用的从底向上的方法,最终可以地推出结果[0,9]的值是8.

  在计算最大时间的过程中,将每次使得Sij最大时的K值记录下来,存储到K[i][j]中去,Sij得出来之后,就可以到出一个K[i][j]的表,根据这个表,可以得到如何不断地将时间划分成最优的两段,直至时间段内有活动充满该时间段,或是时间段内不存在任何活动。有了这个时间划分,我们就可以从这些时间段中分别相应的活动,这样,问题就最终得到了解决。

 

 (代码等续:))

分享到:
评论
2 楼 liyiwen007 2009-06-26  
canofy 写道
3. 否则,Sij=max{Sik+Sij} ,其中、k从i到j依次取值。

这里应该是Sij=max{Sik+Skj} ,应该是笔误吧~


确实确实~!!
没想到会有人看得这么细。想来应该是高手~!


谢谢你!
1 楼 canofy 2009-06-24  
3. 否则,Sij=max{Sik+Sij} ,其中、k从i到j依次取值。

这里应该是Sij=max{Sik+Skj} ,应该是笔误吧~

相关推荐

    算法导论--教师手册

    动态规划是一种通过分解问题为子问题来求解最优解的方法,而贪心算法则是在每一步都做出局部最优选择以期达到全局最优。这两章内容对于解决优化问题具有重要意义。 #### 摊销分析 第十七章“Amortized Analysis”...

    [麻省理工学院-算法导论].Introduction.to.Algorithms.-.Lecture.Notes 算法导论-课堂笔记 讲义

    动态规划是一种解决最优化问题的方法,通过构建子问题的最优解来找到原问题的最优解。典型的动态规划问题有背包问题、最长公共子序列、矩阵链乘法等。动态规划的关键是状态定义和状态转移方程。 六、递归与分治 ...

    算法导论读书笔记

    《算法导论》是计算机科学领域的一本经典之作,它深入浅出地介绍了算法的设计、分析和实现。这本书的第二到第八章涵盖了诸多基础且重要的算法知识,是学习算法的基石。以下是对这些章节主要内容的详细解读: 第二章...

    算法导论答案算法导论教师手册

    《算法导论》通过多个实例,如背包问题、最长公共子序列问题等,详细阐述了动态规划的基本思想和实现技巧。相比之下,贪心算法则在每个步骤都做出局部最优选择,以期达到全局最优解,但并不总是有效,因此理解其适用...

    算法导论(麻省大学还有笔记)

    5. **贪心算法**:适用于局部最优解能保证全局最优的情况,如霍夫曼编码、活动选择问题等。 6. **回溯与分支限界**:在解决组合优化问题时常用,如八皇后问题、N皇后问题等。 7. **数据结构**:如链表、栈、队列、...

    MIT(麻省理工)算法导论笔记

    《MIT(麻省理工)算法导论笔记》是一份详细记录了麻省理工学院(Introduction to Algorithms)课程精华的学习资料。这门课程是全球计算机科学专业学子深入理解算法的基石,其重要性不言而喻。尽管由于文件大小限制,...

    MIT 算法导论 课堂笔记

    通过深入学习这本《MIT算法导论》的课堂笔记,你可以系统地掌握算法的精髓,提高解决问题的能力,为未来的编程生涯打下坚实的基础。同时,Word文档的格式使得笔记易于阅读和整理,方便你在学习过程中随时查阅和复习...

    麻省理工算法导论全套笔记

    《麻省理工算法导论全套笔记》是一份深入学习算法的宝贵资料,源自世界顶级学府麻省理工学院(MIT)的课程。这份笔记涵盖了广泛的算法主题,旨在帮助读者掌握算法设计、分析以及实现的核心概念。以下是根据提供的...

    算法导论读书笔记(整理别人的)

    4. **动态规划**:动态规划是一种解决最优化问题的有效方法,通过将大问题分解为子问题,利用子问题的最优解来构造原问题的最优解。例如,背包问题、最长公共子序列问题和斐波那契数列等。 5. **递归与分治**:递归...

    算法导论 学习笔记.pdf

    算法导论学习笔记 本资源是对《算法导论》的学习笔记,涵盖了算法的基础知识、算法分析、函数的增长、递归式等方面的内容。 一、算法基础知识 算法是指将输入转换为输出的一系列计算步骤,目的是为了有效利用...

    [麻省理工学院-算法导论].Lecture.Notes

    《算法导论》是计算机科学领域的一本经典教材,由麻省理工学院(MIT)的教授们编写。这本书深入浅出地介绍了算法的设计、分析以及实现,为学习者提供了理解和解决实际问题的强大工具。以下是对压缩包中各讲座笔记的...

    《算法导论》学习笔记

    ### 《算法导论》学习笔记关键知识点梳理 #### 第一部分:基础知识 ##### 第1章:算法在计算中的作用 1. **算法定义**:算法是一系列明确且有限的指令集合,旨在解决特定问题或执行特定任务。它可以视为将有效...

    [麻省理工学院-算法导论].Introduction.to.Algorithms.-.Lecture.Notes

    4. **贪心算法**:这类算法在每一步选择局部最优解,期望达到全局最优,如霍夫曼编码、活动选择问题等。 5. **分治策略**:将大问题分解为小问题来解决,如归并排序、快速排序、Strassen矩阵乘法等,分治策略是很多...

    麻省理工公开课:算法导论(书、讲义、字幕、笔记、答案)

    - **动态规划**:通过构建子问题解决复杂问题,如斐波那契数列、背包问题等。 - **贪心算法**:每一步选择局部最优解,如霍夫曼编码、Prim最小生成树等。 - **回溯法**:尝试所有可能的路径,如八皇后问题、旅行...

    算法导论 黑皮书 期末复习笔记

    如霍夫曼编码、活动选择问题等,贪心算法在资源分配、任务调度等问题上表现出色。 5. **回溯与分支限界**:用于解决组合优化问题,如八皇后问题、N皇后问题、数独求解等。这两种方法可以有效地在搜索空间中找到解决...

    算法导论系列读书笔记之五

    《算法导论》系列读书笔记之五主要涵盖了指示器随机变量、概率分析以及它们在算法设计与分析中的应用,特别是雇用问题的解决方案。在这个章节中,我们将深入探讨这些概念,以便更好地理解和运用它们。 首先,我们要...

    MIT算法导论字幕

    "MIT算法导论"涵盖了诸多算法主题,包括排序、搜索、图算法、动态规划、贪心算法以及复杂性理论等。这些知识点是构建计算机科学知识体系的基础,对于想要深入理解计算机工作的原理,或是准备参加如ACM国际大学生程序...

    算法导论笔记

    ### 算法导论笔记知识点总结 #### 第二章:算法基础 ##### 插入排序 - **定义**:插入排序是一种简单的排序算法,它通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 - **...

    算法导论 教师手册 英文版 课后思考题答案

    - **讲座笔记**:介绍了动态规划的基本思想,即通过将问题分解成子问题来求解最优解。 - **课后思考题答案**:通过具体的动态规划问题实例,帮助学生理解如何设计相应的算法。 ##### 14. **第十四章:贪心算法** ...

    算法导论英文笔记和答案(较全)

    “动态规划”章节讲解了动态规划的概念和方法,动态规划是一种解决复杂问题的方法,通过将问题分解为更小的子问题来找到最优解。 “贪心算法”章节则着重于介绍贪心算法的原理,贪心算法在每一步选择中都采取在当前...

Global site tag (gtag.js) - Google Analytics