第15章分枝定界法
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
然后从表中选择一个结点作为下一个扩展结点,并 重复上述结点的扩展过程,直到找到所需要的解或活 动表为空时结束。
算法思想
从活结点表中选择下一个扩展结点通常有两种方式。 ①先进先出(FIFO)法。即从活结点表中取出结点的 顺序与加入结点的顺序相同,因此活结点表的性质与队 列的相同。
②最小耗费或最大收益法。由于解空间中每个结点都 有一个对应的耗费或收益,可将活结点表组织成一个优 先队列,并根据结点的耗费所确定的结点优先级别来选 取下一个结点。
最后G成为扩展结点,生成的结点为N和O,两者 所对应的解都不比当前的最优解更好,因此最优解保 持不变,两者都是叶结点而被删除,此时堆变为空, 搜索过程结束,到达结点L 的搜索为最优解。
已知n = 3, w = [20, 15, 15], p = [40, 25, 25], c = 30
算法思想
已知n = 3, w = [20, 15, 15], p = [40, 25, 25], c = 30
例15-1
A被删除,由于B的收益值比C的大,因此对B进行 扩展,得到结点D和E,D是不可行的而被删除,E加 入堆中。由于E具有收益值40,而C为0,因此E成为 下一个扩展结点,生成结点J和K,J不可行而被删除, K是一个可行的解,因此K作为目前能找到的最优解 而被记录下来,然后K被删除。
例15-1
接下来扩展结点F,它产生两个孩子L和M,L代表一 个可行的解且其收益值为50,M代表另一个收益值为 15的可行解。G是最后一个扩展结点,它的孩子N和O 都是可行的。由于活结点队列变为空,因此搜索过程 终止,最佳解的收益值为50。
从上述过程可看出,在解空间树上进行的FIFO分枝定界方法 类似于从根结点出发的广度优先搜索,它们的主要区别是在 FIFO分枝定界法中不可行的结点不会被搜索。
第15章 分枝定界法
算法思想
分枝定界法是另一种系统地搜索解空间的方法,其 解空间树也为一棵有序树,如排序树或子集树。它 与回溯法的主要区别在于对当前扩展结点所采用的扩 展方式不同。
在分枝定界法中,每一个活结点有且仅有一次机会 变成扩展结点,活结点一旦变为扩展结点,就会一次 性地生成其所有的孩子结点(即新结点),在这些孩 子结点中,那些不可能导出可行解或最优解的结点将 被舍弃,其余的孩子结点被加入活结点表中。
应 用
点队列中元素的类型是QNode(见以下程序)。这里, 当 且 仅 当 结 点 是 它 的 父 结 点 的 左 孩 子 时 , LChild 为 true。
计算最优子集的分枝定界法:
应 用
应 用
(4)最大收益分枝定界
在对子集树进行最大收益分枝定界搜索时,活结点
列表是一个最大优先级队列,其中每个活结点x都有
应 用
以下程序中的函数AddLiveNode用于把bbnode类型的 活结点加到子树中,并把HeapNode类型的活结点插入最 大堆中。
程序中的函数MaxLoading定义了一个容量为1000的最
应
大堆,因此,可用它来解决优先队列中活结点数在任何时 候都不超过1000的装箱问题。
用
应 用
0-1背包问题 0-1背包问题的最大收益分枝定界算法(见以下
程序)可通过上一个程序产生,它定义的类Knap类似 于回溯法中的类Knap(见第14章),函数MaxProfit
应 Knapsack在子集树中执行最大收益分枝定界搜索。
用
应 用
应 用
最大完备子图 完备子图问题的解空间树也是一个子集树,故可
都是O(2n)。
(2)改进 可通过使用定界函数来改进上述问题的求解过程, 即只有当右孩子对应的重量加上剩余货箱的重量超出 当前最优解时才选择右孩子,如以下程序所示。
应 用
应 用
(3)寻找最优子集
为了找到最优子集,需要记录从每个活结点到达根
的路径,因此在找到最优装载所对应的叶结点之后,
可利用所记录的路径返回到根结点来设置x的值。活结
并且其他任何活结点都不可能扩展到具有更大重量的 叶结点时,最优装载的搜索终止。
上述策略可用两种方法来实现。一种方法是,最大 优先级队列中的活结点都是互相独立的,因此每个活 结点内部必须记录从子集树的根到此结点的路径。一 旦找到了最优装载所对应的叶结点,就利用这些路径
应 信息来计算x值。 用 另一种方法是,除了把结点加入最大优先队列之外,
使用与装箱问题、背包问题相同的最大收益分枝定界 方法来求解这种问题,见以下程序。
应 用
应 用
解空间树中的结点类型为bbnode,最大优先
队列中元素的类型是CliqueNode。当从最大优先队
列中选取元素时,选取的是具有最大un值的元素。
函数AddCliqueNode用于向生成的子树和最大堆中
应
加入结点。
与回溯法类似,也可使用一个定界函数来减少所产生的解空 间树结点数目,以此加速最优解的搜索过程。定界函数为最大 收益设置了一个上限,通过展开一个特殊的结点可能获得这个 最大收益。如果一个结点的定界函数值不大于目前最优解的收 益值,则此结点被删除而不展开。更进一步地,在最大收益分 枝定界法中,可使结点按照它们收益的定界函数值的非升序从 堆中取出,使搜索过程从可能到达一个好的叶结点的活结点出 发,而不是从w = [20, 15, 15], p = [40, 25, 25], c = 30
由于只剩下一个活结点C在堆中,因此C作为扩展 结点被展开,生成F、G两个结点加入堆中。F的收益 值为25,因此成为下一个扩展结点,展开后得到结点 L和M,L所对应的解作为当前最优解被记录下来。 由于L和M是叶结点,因此同时都被删除,
如果查找的是具有最小耗费的解,则活结点表可用最 小堆来建立,下一个扩展结点就是具有最小耗费的活结 点;如果查找的是具有最大收益的解,则可用最大堆来 构造活结点表,下一个扩展结点便是具有最大收益的活 结点。
例15-1
下面分别用FIFO分枝定界法和最大收益分枝定界法 解决例14-1的背包问题并进行比较,即n = 3,w = [20, 15, 15],p = [40, 25, 25],c = 30,它们的解空间也与上一章 例的解空间相同。
应
一个相应的重量上限(即最大收益)。这个重量上限
用
是结点x相应的重量加上剩余货箱的总重量,所有的
活结点按其重量上限的递减顺序变为扩展结点。
需要注意的是,对任意一个结点x,其子树中不可 能存在重量超过结点x重量的结点。另外,当叶结点 对应的重量等于它的重量上限时,可得出结论:在最
大收益分枝定界算法中,当某个叶结点成为扩展结点
②最大收益分枝定界法使用一个最大堆,其中的扩展结点按 照每个活结点收益值的降序,或者按照活结点任意子树的叶结 点所能获得的收益估计值的降序,从队列中取出。该方法的搜 索过程也以解空间树中的结点A作为初始结点,进行扩展后得到 结点B和C,两者都是可行的并被加入堆中,结点B获得的收益 值是40(设x1=1),C获得的收益值为0。
用
函数BBMaxClique在解空间树中执行最大收益
分枝定界搜索,树的根作为初始的扩展结点。while
循环不断展开扩展结点直到一个叶结点变成扩展结
点,因此最大完备子图已经找到。沿着生成的树中
从叶结点到根的路径,即可构造出这个最大完备子
图。
货箱装船 (1)FIFO分枝定界法 上一章的货箱装船问题主要是寻找第一条船的最大装载方案, 该问题的解空间是一棵子集树。对之前程序进行改造便可得到如 下程序所示的FIFO分枝定界法的程序代码,该方法只是寻找最大 装载的重量。
应 用
应 用
程序中,函数MaxLoading在解空间树中进行分 枝定界搜索。链表队列Q用于保存活结点,它记录各活 结点对应的权值,另外还记录了权值1,以标识每一 层活结点的结尾。函数AddLiveNode用来在搜索过程 中增加结点。搜索中所到达的每个叶结点都对应着一 个可行的解,而每个解都会与目前的最优解进行比较, 以确定最优解。MaxLoading函数的时间和空间复杂度
① FIFO分枝定界利用一个队列来记录活结点,结点 按照FIFO顺序从队列中取出。在该方法的搜索过程中, 初始以根结点A作为扩展结点,活结点队列为空,对A进 行扩展时,生成结点B和C,由于这两个结点都是可行的, 因此都被加入活结点队列中,结点A被删除。
队列
队列
下一个扩展结点B,产生结点D和E,由于D是不可 行的,因此被删除,而E被加入队列中。下一步选择结 点C为扩展结点,生成结点F和G,两者都是可行结点, 加入队列中。下一个扩展结点E生成结点J和K,J不可行 而被删除,K是一个可行的叶结点,并产生一个到目前 为止可行的解,它的收益值为40。
结点还放在另一个独立的树结构中,这个树结构用来 表示所生成的子集树的一部分。当找到最大装载之后, 就可沿着路径从叶结点一步一步返回到根,从而计算 出x值。下面给出后一种方法的实现过程,前一种方 法的实现留给读者实现。 以下程序用HeapNode类型的最大堆来表示最大优 先队列,用bbnode类型来表示子集树中的结点。
回溯法比分枝定界法占用更少的内存空间,回溯法占用的内
存是O(解空间的最大路径长度),而分枝定界所占用的内存为 O(解空间大小)。对于一个子集空间,回溯法需要O(n)的内存 空间,而分枝定界则需要O(2n)的空间。对于排列空间,回溯 需要O(n)的内存空间,分枝定界需要O(n!)的空间。虽然最大
收益(或最小耗费)分枝定界法在许多情况下可能会比回溯法 检查更少的结点,但在实际应用中,它可能在回溯法超出允许 的时间限制之前就超出了内存的限制。
算法思想
从活结点表中选择下一个扩展结点通常有两种方式。 ①先进先出(FIFO)法。即从活结点表中取出结点的 顺序与加入结点的顺序相同,因此活结点表的性质与队 列的相同。
②最小耗费或最大收益法。由于解空间中每个结点都 有一个对应的耗费或收益,可将活结点表组织成一个优 先队列,并根据结点的耗费所确定的结点优先级别来选 取下一个结点。
最后G成为扩展结点,生成的结点为N和O,两者 所对应的解都不比当前的最优解更好,因此最优解保 持不变,两者都是叶结点而被删除,此时堆变为空, 搜索过程结束,到达结点L 的搜索为最优解。
已知n = 3, w = [20, 15, 15], p = [40, 25, 25], c = 30
算法思想
已知n = 3, w = [20, 15, 15], p = [40, 25, 25], c = 30
例15-1
A被删除,由于B的收益值比C的大,因此对B进行 扩展,得到结点D和E,D是不可行的而被删除,E加 入堆中。由于E具有收益值40,而C为0,因此E成为 下一个扩展结点,生成结点J和K,J不可行而被删除, K是一个可行的解,因此K作为目前能找到的最优解 而被记录下来,然后K被删除。
例15-1
接下来扩展结点F,它产生两个孩子L和M,L代表一 个可行的解且其收益值为50,M代表另一个收益值为 15的可行解。G是最后一个扩展结点,它的孩子N和O 都是可行的。由于活结点队列变为空,因此搜索过程 终止,最佳解的收益值为50。
从上述过程可看出,在解空间树上进行的FIFO分枝定界方法 类似于从根结点出发的广度优先搜索,它们的主要区别是在 FIFO分枝定界法中不可行的结点不会被搜索。
第15章 分枝定界法
算法思想
分枝定界法是另一种系统地搜索解空间的方法,其 解空间树也为一棵有序树,如排序树或子集树。它 与回溯法的主要区别在于对当前扩展结点所采用的扩 展方式不同。
在分枝定界法中,每一个活结点有且仅有一次机会 变成扩展结点,活结点一旦变为扩展结点,就会一次 性地生成其所有的孩子结点(即新结点),在这些孩 子结点中,那些不可能导出可行解或最优解的结点将 被舍弃,其余的孩子结点被加入活结点表中。
应 用
点队列中元素的类型是QNode(见以下程序)。这里, 当 且 仅 当 结 点 是 它 的 父 结 点 的 左 孩 子 时 , LChild 为 true。
计算最优子集的分枝定界法:
应 用
应 用
(4)最大收益分枝定界
在对子集树进行最大收益分枝定界搜索时,活结点
列表是一个最大优先级队列,其中每个活结点x都有
应 用
以下程序中的函数AddLiveNode用于把bbnode类型的 活结点加到子树中,并把HeapNode类型的活结点插入最 大堆中。
程序中的函数MaxLoading定义了一个容量为1000的最
应
大堆,因此,可用它来解决优先队列中活结点数在任何时 候都不超过1000的装箱问题。
用
应 用
0-1背包问题 0-1背包问题的最大收益分枝定界算法(见以下
程序)可通过上一个程序产生,它定义的类Knap类似 于回溯法中的类Knap(见第14章),函数MaxProfit
应 Knapsack在子集树中执行最大收益分枝定界搜索。
用
应 用
应 用
最大完备子图 完备子图问题的解空间树也是一个子集树,故可
都是O(2n)。
(2)改进 可通过使用定界函数来改进上述问题的求解过程, 即只有当右孩子对应的重量加上剩余货箱的重量超出 当前最优解时才选择右孩子,如以下程序所示。
应 用
应 用
(3)寻找最优子集
为了找到最优子集,需要记录从每个活结点到达根
的路径,因此在找到最优装载所对应的叶结点之后,
可利用所记录的路径返回到根结点来设置x的值。活结
并且其他任何活结点都不可能扩展到具有更大重量的 叶结点时,最优装载的搜索终止。
上述策略可用两种方法来实现。一种方法是,最大 优先级队列中的活结点都是互相独立的,因此每个活 结点内部必须记录从子集树的根到此结点的路径。一 旦找到了最优装载所对应的叶结点,就利用这些路径
应 信息来计算x值。 用 另一种方法是,除了把结点加入最大优先队列之外,
使用与装箱问题、背包问题相同的最大收益分枝定界 方法来求解这种问题,见以下程序。
应 用
应 用
解空间树中的结点类型为bbnode,最大优先
队列中元素的类型是CliqueNode。当从最大优先队
列中选取元素时,选取的是具有最大un值的元素。
函数AddCliqueNode用于向生成的子树和最大堆中
应
加入结点。
与回溯法类似,也可使用一个定界函数来减少所产生的解空 间树结点数目,以此加速最优解的搜索过程。定界函数为最大 收益设置了一个上限,通过展开一个特殊的结点可能获得这个 最大收益。如果一个结点的定界函数值不大于目前最优解的收 益值,则此结点被删除而不展开。更进一步地,在最大收益分 枝定界法中,可使结点按照它们收益的定界函数值的非升序从 堆中取出,使搜索过程从可能到达一个好的叶结点的活结点出 发,而不是从w = [20, 15, 15], p = [40, 25, 25], c = 30
由于只剩下一个活结点C在堆中,因此C作为扩展 结点被展开,生成F、G两个结点加入堆中。F的收益 值为25,因此成为下一个扩展结点,展开后得到结点 L和M,L所对应的解作为当前最优解被记录下来。 由于L和M是叶结点,因此同时都被删除,
如果查找的是具有最小耗费的解,则活结点表可用最 小堆来建立,下一个扩展结点就是具有最小耗费的活结 点;如果查找的是具有最大收益的解,则可用最大堆来 构造活结点表,下一个扩展结点便是具有最大收益的活 结点。
例15-1
下面分别用FIFO分枝定界法和最大收益分枝定界法 解决例14-1的背包问题并进行比较,即n = 3,w = [20, 15, 15],p = [40, 25, 25],c = 30,它们的解空间也与上一章 例的解空间相同。
应
一个相应的重量上限(即最大收益)。这个重量上限
用
是结点x相应的重量加上剩余货箱的总重量,所有的
活结点按其重量上限的递减顺序变为扩展结点。
需要注意的是,对任意一个结点x,其子树中不可 能存在重量超过结点x重量的结点。另外,当叶结点 对应的重量等于它的重量上限时,可得出结论:在最
大收益分枝定界算法中,当某个叶结点成为扩展结点
②最大收益分枝定界法使用一个最大堆,其中的扩展结点按 照每个活结点收益值的降序,或者按照活结点任意子树的叶结 点所能获得的收益估计值的降序,从队列中取出。该方法的搜 索过程也以解空间树中的结点A作为初始结点,进行扩展后得到 结点B和C,两者都是可行的并被加入堆中,结点B获得的收益 值是40(设x1=1),C获得的收益值为0。
用
函数BBMaxClique在解空间树中执行最大收益
分枝定界搜索,树的根作为初始的扩展结点。while
循环不断展开扩展结点直到一个叶结点变成扩展结
点,因此最大完备子图已经找到。沿着生成的树中
从叶结点到根的路径,即可构造出这个最大完备子
图。
货箱装船 (1)FIFO分枝定界法 上一章的货箱装船问题主要是寻找第一条船的最大装载方案, 该问题的解空间是一棵子集树。对之前程序进行改造便可得到如 下程序所示的FIFO分枝定界法的程序代码,该方法只是寻找最大 装载的重量。
应 用
应 用
程序中,函数MaxLoading在解空间树中进行分 枝定界搜索。链表队列Q用于保存活结点,它记录各活 结点对应的权值,另外还记录了权值1,以标识每一 层活结点的结尾。函数AddLiveNode用来在搜索过程 中增加结点。搜索中所到达的每个叶结点都对应着一 个可行的解,而每个解都会与目前的最优解进行比较, 以确定最优解。MaxLoading函数的时间和空间复杂度
① FIFO分枝定界利用一个队列来记录活结点,结点 按照FIFO顺序从队列中取出。在该方法的搜索过程中, 初始以根结点A作为扩展结点,活结点队列为空,对A进 行扩展时,生成结点B和C,由于这两个结点都是可行的, 因此都被加入活结点队列中,结点A被删除。
队列
队列
下一个扩展结点B,产生结点D和E,由于D是不可 行的,因此被删除,而E被加入队列中。下一步选择结 点C为扩展结点,生成结点F和G,两者都是可行结点, 加入队列中。下一个扩展结点E生成结点J和K,J不可行 而被删除,K是一个可行的叶结点,并产生一个到目前 为止可行的解,它的收益值为40。
结点还放在另一个独立的树结构中,这个树结构用来 表示所生成的子集树的一部分。当找到最大装载之后, 就可沿着路径从叶结点一步一步返回到根,从而计算 出x值。下面给出后一种方法的实现过程,前一种方 法的实现留给读者实现。 以下程序用HeapNode类型的最大堆来表示最大优 先队列,用bbnode类型来表示子集树中的结点。
回溯法比分枝定界法占用更少的内存空间,回溯法占用的内
存是O(解空间的最大路径长度),而分枝定界所占用的内存为 O(解空间大小)。对于一个子集空间,回溯法需要O(n)的内存 空间,而分枝定界则需要O(2n)的空间。对于排列空间,回溯 需要O(n)的内存空间,分枝定界需要O(n!)的空间。虽然最大
收益(或最小耗费)分枝定界法在许多情况下可能会比回溯法 检查更少的结点,但在实际应用中,它可能在回溯法超出允许 的时间限制之前就超出了内存的限制。