流水线作业动态规划算法分析
算法设计与分析中的动态规划

算法设计与分析中的动态规划动态规划是一种常用的算法设计与分析方法,它在解决各种实际问题时具有广泛的应用。
动态规划的基本思想是将问题划分为若干个子问题,通过求解子问题的最优解来得到原问题的最优解。
本文将介绍动态规划的基本概念、应用场景以及算法的设计与分析方法。
一、动态规划的基本概念动态规划有三个基本要素,即最优子结构、边界条件和状态转移方程。
最优子结构是指原问题的最优解可以通过求解子问题的最优解得到。
边界条件是指最小的子问题的解,也就是动态规划中的初始条件。
状态转移方程是指原问题与子问题之间的关系,通过状态转移方程可以将原问题的解与子问题的解联系起来。
二、动态规划的应用场景动态规划广泛应用于各个领域,比如图论、字符串处理、计算几何等。
在图论中,动态规划可以用来求解最短路径问题;在字符串处理中,动态规划可以用来求解最长公共子序列问题;在计算几何中,动态规划可以用来求解最大矩形面积问题。
除此之外,动态规划还可以用来解决一些组合优化问题,比如背包问题和旅行商问题。
三、动态规划的算法设计与分析方法动态规划的算法设计与分析方法通常包括以下几个步骤:定义状态、确定状态转移方程、初始化边界条件、计算状态值以及求解最优解。
在定义状态时,需要明确状态变量的含义,以及状态之间的关系。
确定状态转移方程是动态规划的核心步骤,需要根据实际问题来构造合适的状态转移方程。
初始化边界条件是指求解最小子问题的解,通常需要根据实际问题来确定。
计算状态值是指利用状态转移方程来逐步求解子问题的最优解。
最后,通过求解最优解来得到原问题的解。
四、动态规划的实例分析以背包问题为例,说明动态规划的实际应用。
假设有一个背包,它的容量为C。
现有n个物品,每个物品的重量为w[i],价值为v[i]。
要求选取若干个物品放入背包中,使得背包所装物品的总价值最大。
这个问题可以通过动态规划来求解,具体步骤如下:1. 定义状态:dp[i][j]表示前i个物品放入容量为j的背包中所得到的最大价值。
算法设计与分析中的动态规划

算法设计与分析中的动态规划动态规划是一种常用的算法设计与分析技术,通常用于求解具有重叠子问题和最优子结构性质的问题。
它的核心思想是将原问题分解为更小的子问题,并通过递推关系式将子问题的解整合为原问题的解。
在算法设计与分析领域,动态规划广泛应用于优化问题、最短路径问题、序列比对问题等。
一、动态规划的基本特征动态规划算法的正确性基于两个重要的特征:重叠子问题和最优子结构。
1. 重叠子问题重叠子问题是指在求解原问题时,子问题之间存在相互重叠的情况。
也就是说,子问题之间不是独立的,它们具有一定的重复性。
动态规划算法利用这个特征,通过保存已经求解过的子问题的解,避免重复计算,提高算法的效率。
2. 最优子结构最优子结构是指问题的最优解可以通过子问题的最优解推导得到。
也就是说,原问题的最优解可以通过一系列子问题的最优解进行构造。
这个特征是动态规划算法能够求解最优化问题的关键。
二、动态规划的基本步骤1. 确定状态动态规划算法需要明确问题的状态,即问题需要用哪些参数来描述。
状态一般与原问题和子问题的解相关。
2. 定义状态转移方程状态转移方程描述原问题与子问题之间的关系。
通过递推关系式,将原问题分解为更小的子问题,并将子问题的解整合为原问题的解。
3. 初始化根据问题的实际需求,对初始状态进行设定,并计算出初始状态的值。
这一步骤是递推关系式的起点。
4. 递推计算根据状态转移方程,通过递推关系式计算出子问题的解,并将子问题的解整合为原问题的解。
这一步骤通常采用迭代的方式进行。
5. 求解目标问题通过递推计算得到原问题的解,即为最优解或者问题的答案。
三、动态规划的应用动态规划算法在实际问题中具有广泛的应用。
下面以两个经典问题为例,介绍动态规划在实际中的应用。
1. 背包问题背包问题是一种经典的优化问题,主要包括0/1背包问题和完全背包问题。
其核心思想是在限定的背包容量下,选择一些具有最大价值的物品放入背包中。
2. 最长公共子序列问题最长公共子序列问题是指给定两个序列,求解它们的最长公共子序列的长度。
问题描述n个作业{1,2,…,n}要在由2台机器M1和M2组成的流

业集S在机器M2的等待时间为b(1)情况下的一个最优调度。则
(1),’(2),…,’(n)是N的一个调度,这个调度所需的时间 为a(1)+T(S,b(1))<a(1)+T’。这与是N的最优调度矛盾。故
T’T(S,b(1))。从而T’=T(S,b(1))。即流水作业调度问题具有
最优子结构的性质。
3
流水作业调度
2. 递归结构
由流水作业调度问题的最优子结构性质可知:
T ( N ,0) min{a i T ( N {i}, bi )}
1 i n
T ( S , t ) min{ai T ( S {i}, bi max{ t ai ,0})}
iS
T(S,t)中的bi+max{t-ai,0}:
的最优值为m(i,j),即m(i,j)是背包容量为j,可选 择物品为i,i+1,…,n时0-1背包问题的最优值。由01背包问题的最优子结构性质,可以建立计算m(i,j)的 递归式如下:
j wn vn m(n, j ) 0 0 j wn
j wi max{m(i 1, j ),m(i 1, j wi ) vi } m(i, j ) 0 j wi m(i 1, j )
2
流水作业调度
1. 最优子结构性质
设是n个流水作业的一个最优调度,所需的加工时间为 a(1)+T’。其中T’是在机器M2的等待时间为b(1)时,安 排作业(2),…,(n)所需的时间。 记S=N-{(1)},则有T’=T(S,b(1))。
由T的最优性可知,T’T(S,b(1))。若T’>T(S,b(1)),设’是作
动态规划算法的详细原理及使用案例

动态规划算法的详细原理及使用案例一、引言动态规划是一种求解最优化问题的算法,它具有广泛的应用领域,如机器学习、图像处理、自然语言处理等。
本文将详细介绍动态规划算法的原理,并提供一些使用案例,以帮助读者理解和应用这一算法的具体过程。
二、动态规划的基本原理动态规划算法通过将问题分解为多个子问题,并利用已解决子问题的解来求解更大规模的问题。
其核心思想是利用存储技术来避免重复计算,从而大大提高计算效率。
具体来说,动态规划算法通常包含以下步骤:1. 定义子问题:将原问题分解为若干个子问题,这些子问题具有相同的结构,但规模更小。
这种分解可以通过递归的方式进行。
2. 定义状态:确定每个子问题的独立变量,即问题的状态。
状态具有明确的定义和可计算的表达式。
3. 确定状态转移方程:根据子问题之间的关系,建立状态之间的转移方程。
这个方程可以是简单的递推关系式、递归方程或其他形式的方程。
4. 解决问题:使用递推或其他方法,根据状态转移方程求解每个子问题,直到获得最终解。
三、动态规划的使用案例1. 背包问题背包问题是动态规划算法的经典案例之一。
假设有一个背包,它能容纳一定重量的物品,每个物品有对应的价值。
目的是在不超过背包总重量的前提下,选取最有价值的物品装入背包。
这个问题可以通过动态规划算法来求解。
具体步骤如下:(1)定义问题:在不超过背包容量的限制下,选取物品使得总价值最大化。
(2)定义状态:令dp[i][j]表示将前i个物品放入容量为j的背包中所能获得的最大价值。
(3)状态转移方程:dp[i][j] = max(dp[i-1][j-w[i]]+v[i], dp[i-1][j]),其中w[i]为第i个物品的重量,v[i]为第i个物品的价值。
(4)解决问题:根据状态转移方程依次计算每个子问题的解,并记录最优解,直到获得最终答案。
2. 最长公共子序列最长公共子序列(Longest Common Subsequence,简称LCS)是一种经典的动态规划问题,它用于确定两个字符串中最长的共同子序列。
动态规划算法

动态规划算法
动态规划算法(Dynamic Programming)是一种解决多阶段最优化决策问题的算法。
它将问题分为若干个阶段,并按照顺序从第一阶段开始逐步求解,通过每一阶段的最优解得到下一阶段的最优解,直到求解出整个问题的最优解。
动态规划算法的核心思想是将问题划分为子问题,并保存已经解决过的子问题的解,以便在求解其他子问题时不需要重新计算,而是直接使用已有的计算结果。
即动态规划算法采用自底向上的递推方式进行求解,通过计算并保存子问题的最优解,最终得到整个问题的最优解。
动态规划算法的主要步骤如下:
1. 划分子问题:将原问题划分为若干个子问题,并找到问题之间的递推关系。
2. 初始化:根据问题的特点和递推关系,初始化子问题的初始解。
3. 递推求解:按照子问题的递推关系,从初始解逐步求解子问题的最优解,直到求解出整个问题的最优解。
4. 得到最优解:根据子问题的最优解,逐步推导出整个问题的最优解。
5. 保存中间结果:为了避免重复计算,动态规划算法通常会使
用一个数组或表格来保存已经求解过的子问题的解。
动态规划算法常用于解决最优化问题,例如背包问题、最长公共子序列问题、最短路径问题等。
它能够通过将问题划分为若干个子问题,并通过保存已经解决过的子问题的解,从而大大减少计算量,提高算法的效率。
总之,动态规划算法是一种解决多阶段最优化决策问题的算法,它通过将问题划分为子问题,并保存已经解决过的子问题的解,以便在求解其他子问题时不需要重新计算,从而得到整个问题的最优解。
动态规划算法能够提高算法的效率,是解决最优化问题的重要方法。
算法 动态规划

算法动态规划
动态规划是一种常见的算法优化技术,它通过将一个大问题划分为多个相互联系的子问题,从而减少计算量,并且能够有效地解决多阶段决策问题。
算法动态规划的基本思想是“化大为小,求解最优”。
具体而言,将原问题分解为若干个相互依赖的子问题,递归地求解这些子问题,并保存子问题的解,从而避免了重复计算。
通过这种方式,可以在有限的时间内得到原问题的最优解。
动态规划算法的核心是建立状态转移方程,即找到子问题之间的关系。
对于每个子问题,我们需要分析其与前一阶段的子问题之间的联系,并通过状态转移方程来描述它们之间的关系。
在求解过程中,我们逐步地计算子问题,直到得到最终的解。
动态规划算法的关键是保存计算过程中的中间结果,以避免重复计算。
为了实现这一点,可以使用一个数组或者一个矩阵来保存每个子问题的解。
在计算每个子问题时,首先查看是否已经计算过这个子问题的解,如果计算过则直接使用,如果还未计算过则先计算,并保存到数组或矩阵中。
通过这种方式,可以大大减少重复计算,提高算法的效率。
动态规划算法在解决一些问题时非常高效,并且能够保证得到最优解。
然而,由于需要保存记忆化数组或矩阵,所以动态规划算法的空间复杂度较高。
因此,在使用动态规划算法时,需要考虑到计算机的内存限制,以避免出现内存溢出的情况。
总结来说,动态规划是一种通过将大问题划分为多个子问题来减少计算量的算法优化技术。
它通过建立状态转移方程,递归地求解子问题,并保存子问题的解,从而得到原问题的最优解。
动态规划算法能够有效地解决多阶段决策问题,并且保证得到最优解,但需要注意内存占用问题。
动态规划算法的原理
动态规划算法的原理
动态规划算法的原理是将一个复杂的问题分解为多个子问题,并存储每个子问题的解,以便在需要时进行查找。
通过动态规划,可以避免重复计算,提高算法的效率。
动态规划算法的基本思想是通过求解子问题的最优解来获得原问题的最优解。
具体步骤如下:
1. 定义状态:将原问题划分为若干个子问题,并确定状态的表示方式。
2. 确定状态转移方程:找到子问题之间的关系,并建立状态转移方程。
3. 初始化边界条件:确定基本情况的解,为后续的状态转移提供依据。
4. 根据状态转移方程,从小规模问题开始逐步推导,直到求解出原问题的最优解。
5. 根据求解出的最优解,可以回溯得到问题的具体解。
动态规划算法常用于求解优化问题,如最长递增子序列、背包问题、矩阵链乘法等。
通过将复杂问题分解为简单问题,并存储子问题的解,动态规划算法可以有效地减少计算量,提高算法的效率。
五种常用算法之二:动态规划算法
五种常⽤算法之⼆:动态规划算法动态规划算法:基本思想: 动态规划算法通常⽤于求解具有某种最优性质的问题。
在这类问题中,可能会有许多可⾏解。
每⼀个解都对应于⼀个值,我们希望找到具有最优值的解。
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若⼲个⼦问题,先求解⼦问题,然后从这些⼦问题的解得到原问题的解。
与分治法不同的是,适合于⽤动态规划求解的问题,经分解得到⼦问题往往不是互相独⽴的。
若⽤分治法来解这类问题,则分解得到的⼦问题数⽬太多,有些⼦问题被重复计算了很多次。
如果我们能够保存已解决的⼦问题的答案,⽽在需要时再找出已求得的答案,这样就可以避免⼤量的重复计算,节省时间。
我们可以⽤⼀个表来记录所有已解的⼦问题的答案。
不管该⼦问题以后是否被⽤到,只要它被计算过,就将其结果填⼊表中。
这就是动态规划法的基本思路。
具体的动态规划算法多种多样,但它们具有相同的填表格式。
动态规划算法与分治法最⼤的差别是:适合于⽤动态规划法求解的问题,经分解后得到的⼦问题往往不是互相独⽴的(即下⼀个⼦阶段的求解是建⽴在上⼀个⼦阶段的解的基础上,进⾏进⼀步的求解)应⽤场景:适⽤动态规划的问题必须满⾜最优化原理、⽆后效性和重叠性。
1.最优化原理(最优⼦结构性质)最优化原理可这样阐述:⼀个最优化策略具有这样的性质,不论过去状态和决策如何,对前⾯的决策所形成的状态⽽⾔,余下的诸决策必须构成最优策略。
简⽽⾔之,⼀个最优化策略的⼦策略总是最优的。
⼀个问题满⾜最优化原理⼜称其具有最优⼦结构性质。
2.⽆后效性将各阶段按照⼀定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态⽆法直接影响它未来的决策,⽽只能通过当前的这个状态。
换句话说,每个状态都是过去历史的⼀个完整总结。
这就是⽆后向性,⼜称为⽆后效性。
3.⼦问题的重叠性动态规划将原来具有指数级时间复杂度的搜索算法改进成了具有多项式时间复杂度的算法。
其中的关键在于解决冗余,这是动态规划算法的根本⽬的。
动态规划算法在资源调度中的最优解分析
动态规划算法在资源调度中的最优解分析资源调度是指合理利用和配置各种资源,以满足不同任务需求的过程。
在现代社会中,资源调度常常涉及到各种复杂的问题,如生产线的优化、交通流量的调配、网络带宽的分配等。
为了解决这些问题,动态规划算法被广泛应用在资源调度的优化过程中,以求得最优解。
动态规划是一种通过将问题划分为子问题,并通过寻找子问题之间的最优解来求解整个问题的算法。
它的基本思想是将原问题分解为若干个子问题,然后将子问题的解存储起来,以避免重复计算。
在资源调度中,可以将资源的分配过程看作是一个决策序列,每个决策点都会对资源调度产生影响,而每个决策点的最优解会影响到后续决策点的最优解。
因此,动态规划算法能够有效地处理资源调度中的决策问题。
在资源调度中,动态规划算法的最优解分析主要涉及如何定义状态、设计状态转移方程以及如何利用已经计算得到的子问题解来求解当前问题的最优解。
首先,我们需要定义合适的状态来描述问题。
在资源调度中,可以将资源的可利用数量作为状态进行描述。
若将资源的可利用数量用i来表示,那么状态可以定义为f(i),表示在资源数量为i的情况下能够达到的最大利用量。
状态的定义要符合问题的特点,并涵盖所有可能的情况。
其次,设计状态转移方程是动态规划算法的关键。
状态转移方程描述了子问题与当前问题之间的关系,通过寻找子问题之间的最优解来求解当前问题的最优解。
在资源调度中,可以根据资源的分配规则设计状态转移方程。
假设资源的分配规则可以用函数g(k)表示,表示将资源分配给k个任务所能够达到的最大效益。
那么,状态转移方程可以定义为:f(i) = max{f(i-k) + g(k)},其中1<=k<=i在这个状态转移方程中,f(i)表示在资源数量为i的情况下能够达到的最大利用量。
通过遍历所有可能的分配情况(k的取值范围),可以找到能够使f(i)最大化的子问题解,进而得到当前问题的最优解。
最后,利用已经计算得到的子问题解来求解当前问题的最优解。
动态规划算法在物流路径规划中的应用研究
动态规划算法在物流路径规划中的应用研究物流路径规划是现代物流管理系统中关键的环节之一。
它的目标是通过优化货物运输路径,实现最佳的物流运输效率。
随着物流业务的不断发展和扩大,如何快速、准确地规划出最佳路径成为一个紧迫的问题。
动态规划算法作为一种常见且高效的优化算法,具备解决物流路径规划问题的潜力。
首先,动态规划算法的核心思想是将一个问题分解成若干个子问题,并逐步求解得到最优解。
其基本步骤包括定义状态,建立状态转移方程,确定初始条件和边界条件,以及计算最优值。
在物流路径规划中,我们可以将问题定义为如何最小化货物运输的时间或成本,然后将整个物流网络分解为若干个子问题,通过计算每个子问题的最优解,最终得到全局的最优路径。
其次,动态规划算法适用于具有最优子结构特性的问题。
在物流路径规划中,各个子问题之间存在着相互重叠、相互影响的关系。
例如,在计算从起点到某一中转站的最短路径时,我们可以利用已经计算出的起点到其他中转站的最短路径信息,通过动态规划算法一步一步地求解出最终的最短路径。
这种最优子结构特性使得动态规划算法在物流路径规划中具备较高的应用价值。
另外,动态规划算法还可以通过定义合适的状态转移方程来处理多个约束条件。
在物流路径规划中,我们通常需要考虑多个因素,如货物的数量、体积、重量,以及各个中转站之间的距离和运输能力等。
通过将这些因素转化为数值并结合状态转移方程的定义,动态规划算法可以有效地求解出满足约束条件的最优路径。
这为实际物流运输中的决策提供了参考依据。
最后,动态规划算法的时间复杂度通常较低,具备较好的计算效率。
这在物流路径规划中尤为重要,因为实际物流运输中可能存在大量的中转站和货物。
通过采用动态规划算法,我们可以在合理的时间范围内得到近似最优的路径规划结果。
当物流需求和网络规模不断扩大时,动态规划算法的高效性将更加凸显。
综上所述,动态规划算法在物流路径规划中具备广泛的应用前景。
通过合理定义问题、构建状态转移方程并利用最优子结构特性,可以实现对物流路径的快速、准确优化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
批处理作业调度动态规划分析与算法实现为简化起见,我们假定所有ai≠0。
因为如果有ai=0的作业,我们可以先对所有ai≠0的作业进行调度,然后把所有ai=0的作业放到最前面执行(可按任意次序)。
最优调度具有如下性质:在所确定的最优调度的排列中去掉第一个执行作业后,剩下的作业排列仍然还是一个最优调度,即该问题具有最优子结构的性质。
而且,在计算规模为n的作业集合的最优调度时,该作业集合的子集合的最优调度会被多次用到,即该问题亦具有高度重复性。
这就引导我们考虑用动态规划法求解。
然而,正如我们下面将会看到的,虽然使用动态规划法可以得到一些有用的结果,但如果不加以某种改进,完全照搬动态规划法会使得算法的时间复杂度成为指数量级。
问题求解的思路如下:设N={1,2,┅,n}是全部作业的集合,作业集S是N的子集合即有S 属于N。
在我们对S中的第一个作业开始进行加工时,机器P2上加工的其它作业可能还尚未完成,不能立即用来对S中的作业进行加工。
假设对机器P2需等待t个时间单位以后才可以用于S中的作业加工(t也可以为0即无须等待),并记g(S,t)为在此情况下完成S中全部作业的最短时间,则可用下述递归表达式来表出g(S,t):g(S,t)=mini∈S{ai+ g(S-{i},bi+max{t-ai,0})} (*)即:当选定作业i为S中第一个加工作业之后,在机器P2上开始对S-{i}中的作业进行加工之前,所需要的等待时间为bi+max{t-ai,0}。
这是因为,若P2在开始加工S中的作业之前需等待t个时间单位且t > ai,则作业i在P1上加工完毕(需时ai)之后,还要再等t-ai个时间单位才能开始在P2上加工;若t≤ai,则作业i在P1上加工完毕之后,立即可以在P2上加工,等待时间为0。
故P2在开始对S-{i}中的作业进行加工之前,所需要的等待时间为bi+max{t-ai,0}。
(bi是作业i在P2上加工所需的时间)。
当S=N即全部作业开始加工时,由于P2上尚无任何正在加工的作业,故此时等待时间t=0。
于是我们有:g(N,0)=min1≤i≤n{ai+ g(N-{i},bi)}。
虽然根据(*)式我们可以编写出计算g(N,0)的程序,但该算法的时间复杂度为指数量级,因为算法中对N的每一个非空子集都要进行一次计算,而N的非空子集共有2n-1个。
因此,我们不能直接使用动态规划法来求解该问题,而需要对算法作一定的改进。
设π是作业子集S的某一个调度,该调度首先安排作业i,其次安排作业j,P2需等待t个时间单位以后才可以用于S中的作业加工。
记t’= bi+max{t-ai,0},则由(*)式调度π的g(S,t)可写为g(S,t)=ai+ g(S-{i}, t’)= ai+ aj+ g(S-{i,j}, bj+max{t’-aj,0})。
由于x+ max{y1, y2,?,yn}= max{x+y1,x+y2,?,x+yn},t’= bi+max{t-ai,0},所以bj+max{t’-aj,0}=bj+max{bi+max{t-ai,0}-aj, 0}= bj+bi -aj+max{max{t-ai,0},aj-bi}=bj+ bi - aj +max{t-ai, 0, aj-bi}=bj+ bi - aj - ai +max{t, ai, ai+aj-bi}。
记tij= bj+ bi - aj - ai +max{t, ai, ai+aj-bi}(=bj+max{t’-aj,0}),则调度π的g(S,t)=ai+ aj+ g(S-{i,j}, tij)。
将调度π中的作业i与j的加工次序交换(其它加工次序不变)所得调度记为π’,则调度π’的最早完工时间g’(S,t)=ai+ aj+ g(S-{i,j}, tji)。
显然,若tij ≤ tji,则有g(S,t) ≤ g’(S,t)即i在前j在后的安排用时较少;反之,若tij >tji,则j在前i在后的安排用时较少。
因此,我们要找出判断tij与tji之间的大小关系的表达式。
由于tij-tji= max{t, ai, ai+aj-bi}-max{t, aj, ai+aj-bj},故我们只要比较max{t, ai,ai+aj-bi}与max{t,aj,ai+aj-bj}的大小就可以了, 即tij ≤tji当且仅当max{t,ai,ai+aj-bi} ≤ max{t,aj,ai+aj-bj}。
由于max{t, ai,ai+aj-bi}≤max{t,aj, ai+aj-bj}对任何t ≥ 0成立,当且仅当max{ai,ai+aj-bi} ≤max{aj, ai+aj-bj}成立,当且仅当ai+aj+max{-aj,-bi}≤ai+aj+max{-ai,-bj}成立,当且仅当max{-aj,-bi}≤ max{-ai,-bj}成立,当且仅当min{aj,bi} ≥ min{ai,bj}成立(此式称为Johnson不等式)。
即当min{ai,aj ,bi,bj}为ai或者bj时,Johnson不等式成立,此时把i排在前j排在后的调度用时较少;反之,若min{ai,aj,bi,bj}为aj或者bi时,则j排在前i排在后的调度用时较少。
将此情况推广到一般。
当min{ a1, a2,┅,an ,b1,b2,┅,bn}=ak时,则对任何i≠k,都有min{ai,bk}≥ min{ak, bi}成立,故此时应将作业k安排在最前面,作为最优调度的第一个执行的作业;当min{ a1, a2,┅, an , b1, b2,┅, bn }= bk时,则对任何i≠k,也都有min{ak, bi}≥min{ai, bk}成立,故此时应将作业k安排在最后面,作为最优调度的最后一个执行的作业。
n个作业中首先开工(或最后开工)的作业确定之后,对剩下的n-1个作业采用相同方法可再确定其中的一个作业,应作为n-1个作业中最先或最后执行的作业;反复使用这个方法直到最后只剩一个作业为止,最优调度就确定了。
e.g. n=4, (a1, a2, a3, a4)=(5,12,4,8), (b1, b2, b3,b4)=(6,2,14,7)。
(a1, a2, a3, a4)与(b1, b2, b3, b4)合起来排序的结果为(2,4,5,6,7,8,12,14)=(b2,a3,a1,b1,b4,a4,a2, b3)。
最小数是b2,故作业2应安排为最后一个作业:π(4)←2。
次小数是a3,故作业3应安排为第一个作业:π(1)←3。
第3小数是a1,故作业1应安排为第二个作业:π(2)←1。
第4小数是b1,因作业1已安排过,故转去看下一个数。
第5小数是b4,故作业4应安排为倒数第二个作业:π(3)←4。
至此,所有作业均已安排完毕。
本例的调度图解如下。
求解该问题的算法如下:1. 建立长为2n的数组C,将a1, a2,┅, an依次放入C[1]~ C[n]中,b1, b2,┅, bn依次放入C[n+1]~ C[2n]中。
/* O(n), 下面将对这2n个数进行排序*/2. 对长为2n的数组D进行初始化:D[1]~ D[n]中依次放1,2,┅,n,D[n+1]~ D[2n]中依次放-1,-2,┅,-n。
/* O(n), 分别对应于a1, a2,┅, an和b1, b2,┅, bn的下标*/3. 对数组C进行排序,D[k]始终保持与C[k]的对应关系。
(若C[i]与C[j]对换,则D[i]也与D[j]对换。
或将C,D放在同一结构体中。
)当a1, a2,┅, an及b1, b2,┅, bn按从小到大次序排好之后,D[1]~ D[2n]也就按从小到大的次序记录了这些ai和bj的下标即作业号(bj的下标前有一负号以区别于ai))。
/*O(n log n)*/4. 将E[1]~ E[n]全部置为“No”。
/* O(n),表示所有任务均尚未被安排*/5. 下标变量初始化:i←1;j←n;k←1;/*O(1),i指向当前最左空位F[i],放当前应最先安排的作业号;*//* j指向当前最右空位F[j],放当前应最后安排的作业号;*/ /* k从1开始逐次增1,*//* D[k](或-D[k])按ai和bj从小到大的次序依次给出作业号*/6. while i ≤ j do { /* 作业尚未安排完毕,i从小到大, j 从大到小*/if D[k] > 0 then {if E[D[k]]为“No”then/*作业D[k]放在当前最左空位*/{F[i]←D[k]; i增1; E[D[k]] 置为“Yes”}}else if E[–D[k]]为“No”then/*作业–D[k]放在当前最右空位*/{F[j]←–D[k]; j减1; E[–D[k]] 置为“Yes”}}k增1;}算法分析:第1,2,4句的初始化均只需要O(n)时间,第3句的排序需要O(n log n)时间,第5句的下标变量初始化只需要O(1)时间,至于第6句的循环,由于在D[1]~ D[2n]中放的是1,2,┅,n,-1,-2,┅,-n共2n个数,(注意C数组排序后次序已经打乱)且每执行一次循环k均增1,故当执行2n次时,D数组中存放的每一个m或-m(m=1,2,┅,n)都会被遇到,若m先遇到,则使得i增1;若-m先遇到,则使得j减1,故最多执行完k=2n-1时,必然要有i > j,使得循环中止。
∴算法的时间复杂度为O(n log n)。
小结:满足1)高度重复性 2)最优子结构性质时。