当前位置:文档之家› 分枝定界法讲义_代码

分枝定界法讲义_代码

分枝定界法讲义_代码
分枝定界法讲义_代码

第5 章分枝定界

任何美好的事情都有结束的时候。现在我们学习的是本书的最后一章。幸运的是,本章用到的大部分概念在前面各章中已作了介绍。类似于回溯法,分枝定界法在搜索解空间时,也经常使用树形结构来组织解空间(常用的树结构是第1 6章所介绍的子集树和排列树)。然而与回溯法不同的是,回溯算法使用深度优先方法搜索树结构,而分枝定界一般用宽度优先或最小耗费方法来搜索这些树。本章与第1 6章所考察的应用完全相同,因此,可以很容易比较回溯法与分枝定界法的异同。相对而言,分枝定界算法的解空间比回溯法大得多,因此当内存容量有限时,回溯法成功的可能性更大。

算法思想

分枝定界(branch and bound)是另一种系统地搜索解空间的方法,它与回溯法的主要区别在于对E-节点的扩充方式。每个活节点有且仅有一次机会变成E-节点。当一个节点变为E-节点时,则生成从该节点移动一步即可到达的所有新节点。在生成的节点中,抛弃那些不可能导出(最优)可行解的节点,其余节点加入活节点表,然后从表中选择一个节点作为下一个E-节点。从活节点表中取出所选择的节点并进行扩充,直到找到解或活动表为空,扩充过程才结束。

有两种常用的方法可用来选择下一个E-节点(虽然也可能存在其他的方法):

1) 先进先出(F I F O)即从活节点表中取出节点的顺序与加入节点的顺序相同,因此活节点表的性质与队列相同。

2) 最小耗费或最大收益法在这种模式中,每个节点都有一个对应的耗费或收益。如果查找一个具有最小耗费的解,则活节点表可用最小堆来建立,下一个E-节点就是具有最小耗费的活节点;如果希望搜索一个具有最大收益的解,则可用最大堆来构造活节点表,下一个E-节点是具有最大收益的活节点。

例5-1 [迷宫老鼠] 考察图16-3a 给出的迷宫老鼠例子和图1 6 - 1的解空间结构。使用F I F O分枝定界,初始时取(1,1)作为E-节点且活动队列为空。迷宫的位置( 1 , 1)被置为1,以免再次返回到这个位置。(1,1)被扩充,它的相邻节点(1,2)和(2,1)加入到队列中(即活节点表)。为避免再次回到这两个位置,将位置(1,2)和(2,1)置为1。此时迷宫如图1 7 - 1 a所示,E-节点(1,1)被删除。

节点(1,2)从队列中移出并被扩充。检查它的三个相邻节点(见图1 6 - 1的解空间),只有(1,3)是可行的移动(剩余的两个节点是障碍节点),将其加入队列,并把相应的迷宫位置置为1,所得到的迷宫状态如图17-1b 所示。节点(1,2)被删除,而下一个E-节点(2,1)将会被取出,当此节点被展开时,节点(3,1)被加入队列中,节点(3,1)被置为1,节点(2,1)被删除,所得到的迷宫如图17-1c 所示。此时队列中包含(1,3)和(3,1)两个节点。随后节点(1,3)变成下一个E-节点,由于此节点不能到达任何新的节点,所以此节点即被删除,节点(3,1)成为新的E-节点,将队列清空。节点(3,1)展开,(3,2)被加入队列中,而(3,1)被删除。(3,2)变为新的E-节点,展开此节点后,到达节点(3,3),即迷宫的出口。

使用F I F O搜索,总能找出从迷宫入口到出口的最短路径。需要注意的是:利用回溯法找到的路径却不一定是最短路径。有趣的是,程序6 - 11已经给出了利用F I F O分枝定界搜索从迷宫的(1,1)位置到(n,n)位置的最短路径的代码。

例5-2 [0/1背包问题] 下面比较分别利用F I F O分枝定界和最大收益分枝定界方法来解决如下背包问题:n=3,

w=[20,15,15], p=[40,25,25], c= 3 0。F I F O分枝定界利用一个队列来记录活节点,节点将按照F I F O顺序从队列中取出;而最大收益分枝定界使用一个最大堆,其中的E-节点按照每个活节点收益值的降序,或是按照活节点任意子树的叶节点所能获得的收益估计值的降序从队列中取出。本例所使用的背包问题与例1 6 . 2相同,并且有相同的解空间树。

使用F I F O分枝定界法搜索,初始时以根节点A作为E-节点,此时活节点队列为空。当节点

A展开时,生成了节点B和C,由于这两个节点都是可行的,因此都被加入活节点队列中,节点A被删除。下一个E-节点是B,展开它并产生了节点D和E,D是不可行的,被删除,而E被加入队列中。下一步节点C成为E-节点,它展开后生成节点F和G,两者都是可行节点,加入队列中。下一个E-节点E生成节点J和K,J不可行而被删除,K是一个可行的叶节点,并产生一个到目前为止可行的解,它的收益值为4 0。

下一个E-节点是F,它产生两个孩子L、M,L代表一个可行的解且其收益值为5 0,M代表另一个收益值为1 5的可行解。G是最后一个E-节点,它的孩子N和O都是可行的。由于活节点队列变为空,因此搜索过程终止,最佳解的收益值为5 0。

可以看到,工作在解空间树上的F I F O分枝定界方法非常象从根节点出发的宽度优先搜索。它们的主要区别是在F I F O

分枝定界中不可行的节点不会被搜索。最大收益分枝定界算法以解空间树中的节点A作为初始节点。展开初始节点得到节点B和C,两者都是可行的并被插入堆中,节点B获得的收益值是4 0(设x1 = 1),而节点C得到的收益值为0。A被删除,B 成为下一个E-节点,因为它的收益值比C的大。当展开B时得到了节点D和E,D是不可行的而被删除,E加入堆中。由于E具有收益值4 0,而C为0,因为E成为下一个E-节点。

展开E时生成节点J和K,J不可行而被删除,K是一个可行的解,因此K为作为目前能找到的最优解而记录下来,然后K被删除。由于只剩下一个活节点C在堆中,因此C作为E-节点被展开,生成F、G两个节点插入堆中。F的收益值为2 5,因此成为下一个E-节点,展开后得到节点L和M,但L、M都被删除,因为它们是叶节点,同时L所对应的解被作为当前最优解记录下来。最终,G成为E-节点,生成的节点为N和O,两者都是叶节点而被删除,两者所对应的解都不比当前的最优解更好,因此最优解保持不变。此时堆变为空,没有下一个E-节点产生,搜索过程终止。终止于J的搜索即为最优解。

犹如在回溯方法中一样,可利用一个定界函数来加速最优解的搜索过程。定界函数为最大收益设置了一个上限,通过展开一个特殊的节点可能获得这个最大收益。如果一个节点的定界函数值不大于目前最优解的收益值,则此节点会被删除而不作展开,更进一步,在最大收益分枝定界方法中,可以使节点按照它们收益的定界函数值的非升序从堆中取出,而不是按照节点的实际收益值来取出。这种策略从可能到达一个好的叶节点的活节点出发,而不是从目前具有较大收益值的节点出发。

例5-3 [旅行商问题] 对于图1 6 - 4的四城市旅行商问题,其对应的解空间为图1 6 - 5所示的排列树。F I F O分枝定界使用节点B作为初始的E-节点,活节点队列初始为空。当B展开时,生成节点C、D和E。由于从顶点1到顶点2,3,4都有边相连,所以C、D、E三个节点都是可行的并加入队列中。当前的E-节点B被删除,新的E-节点是队列中的第一个节点,即节点C。因为在图1 6 - 4中存在从顶点2到顶点3和4的边,因此展开C,生成节点F和G,两者都被加入队列。下一步,D成为E-节点,接着又是E,到目前为止活节点队列中包含节点F到K。下一个E-节点是F,展开它得到了叶节点L。至此找到了一个旅行路径,它的开销是5 9。展开下一个E-节点G,得到叶节点M,它对应于一个开销为6 6的旅行路径。接着H 成为E-节点,从而找到叶节点N,对应开销为2 5的旅行路径。下一个E-节点是I,它对应的部分旅行1 - 3 - 4的开销已经为2 6,超过了目前最优的旅行路径,因此,I不会被展开。最后,节点J,K成为E-节点并被展开。经过这些展开过程,队列变为空,算法结束。找到的最优方案是节点N所对应的旅行路径。

如果不使用F I F O方法,还可以使用最小耗费方法来搜索解空间树,即用一个最小堆来存储活节点。这种方法同样从节点B开始搜索,并使用一个空的活节点列表。当节点B展开时,生成节点C、D和E并将它们加入最小堆中。在最小堆的节点中,E具有最小耗费(因为1 - 4的局部旅行的耗费是4),因此成为E-节点。展开E生成节点J和K并将它们加入最小堆,这两个节点的耗费分别为1 4和2 4。此时,在所有最小堆的节点中,D具有最小耗费,因而成为E-节点,并生成节点H和I。至此,最小堆中包含节点C、H、I、J和K,H具有最小耗费,因此H成为下一个E-节点。展开节点E,得到一个完整的旅行路径1 - 3 - 2 - 4 - 1,它的开销是2 5。节点J是下一个E-节点,展开它得到节点P,它对应于一个耗费为2 5的旅行路径。节点K和I是下两个E-节点。由于I的开销超过了当前最优的旅行路径,因此搜索结束,而剩下的所有活节点都不能使我们找到更优的解。

对于例5 - 2的背包问题,可以使用一个定界函数来减少生成和展开的节点数量。这种函数将确定旅行的最小耗费的下限,这个下限可通过展开某个特定的节点而得到。如果一个节点的定界函数值不能比当前的最优旅行更小,则它将被删除而不被展开。另外,对于最小耗费分枝定界,节点按照它在最小堆中的非降序取出。

在以上几个例子中,可以利用定界函数来降低所产生的树型解空间的节点数目。当设计定界函数时,必须记住主要目的是利用最少的时间,在内存允许的范围内去解决问题。而通过产生具有最少节点的树来解决问题并不是根本的目标。因此,我们需要的是一个能够有效地减少计算时间并因此而使产生的节点数目也减少的定界函数。

回溯法比分枝定界在占用内存方面具有优势。回溯法占用的内存是O(解空间的最大路径长度),而分枝定界所占用的内存为O(解空间大小)。对于一个子集空间,回溯法需要(n)的内存空间,而分枝定界则需要O ( 2n ) 的空间。对于排列空间,回溯需要(n) 的内存空间,分枝定界需要O (n!) 的空间。虽然最大收益(或最小耗费)分枝定界在直觉上要好于回溯法,并且在许多情况下可能会比回溯法检查更少的节点,但在实际应用中,它可能会在回溯法超出允许的时间限制之前就超出了内存的限制。

练习

1. 假定在一个L I F O分枝定界搜索中,活节点列表的行为与堆栈相同,请使用这种方法来解决例5 - 2的背包问题。L I F O 分枝定界与回溯有何区别?

2. 对于如下0 / 1背包问题:n=4, p=[4,3,2,1], w=[1,2,3,4], c =6。

1) 画出有四个对象的背包问题的解空间树。

2) 像例1 7 - 2那样,描述用F I F O分枝定界法解决上述问题的过程。

3) 使用程序1 6 - 6的B o u n d函数来计算子树上任一叶节点可能获得的最大收益值,并根据每一步所能得到的最优解对应的定界函数值来判断是否将节点加入活节点列表中。解空间中哪些节点是使用以上机制的F I F O分枝定界方法产生的?

4) 像例1 7 - 2那样,描述用最大收益分枝定界法解决上述问题的过程。

5) 在最大收益分枝定界中,若使用3)中的定界函数,将产生解空间树中的哪些节点?

应用

5.2.1 货箱装船

1. FIFO分枝定界

4 . 2 . 1节的货箱装船问题主要是寻找第一条船的最大装载方案。这个问题是一个子集选择

问题,它的解空间被组织成一个子集树。对程序1 6 - 1进行改造,即得到程序1 7 - 1中的F I F O分枝定界代码。程序1 7 - 1只是寻找最大装载的重量。

程序17-1 货箱装船问题的F I F O分枝定界算法

template

void AddLiveNode(LinkedQueue &Q, T wt,

T& bestw, int i, int n)

{A d d中的N o M e m异常,这项工作留给用户完成。

如果E-节点的两个孩子都已经被生成,则删除该E-节点。从队列中取出下一个E-节点,此时队列必不为空,因为队列中至少含有本层末尾的标识- 1。如果到达了某一层的结尾,则从下一层寻找活节点,当且仅当队列不为空时这些节点存在。当下一层存在活节点时,向队列中加入下一层的结尾标志并开始处理下一层的活节点。

M a x L o a d i n g函数的时间和空间复杂性都是O ( 2n )。

2. 改进

我们可以尝试使用程序1 6 - 2的优化方法改进上述问题的求解过程。在程序1 6 - 2中,只有当右孩子对应的重量加上剩余货箱的重量超出b e s t w时,才选择右孩子。而在程序1 7 - 1中,在i变为n之前,b e s t w的值一直保持不变,因此在i等于n之前对右孩子的测试总能成功,因为b e s t w = 0且r > 0。当i等于n时,不会再有节点加入队列中,因此这时对右孩子的测试不再有效。

如想要使右孩子的测试仍然有效,应当提早改变b e s t w的值。我们知道,最优装载的重量是子集树中可行节点的重量的最大值。由于仅在向左子树移动时这些重量才会增大,因此可以在每次进行这种移动时改变b e s t w的值。根据以上思想,我们设计了程序1 7 - 2。当活节点加入队列时,w t不会超过b e s t w,故b e s t w不用更新。因此用一条直接插入M a x L o a d i n g的简单语句取代了函数A d d L i v e N o d e。

程序17-2 对程序1 7 - 1改进之后

template

T MaxLoading(T w[], T c, int n)

{A d d ( - 1 ) ; / /标记本层的尾部

int i = 1; 寻找最优子集

为了找到最优子集,需要记录从每个活节点到达根的路径,因此在找到最优装载所对应的叶节点之后,就可以利用所记录的路径返回到根节点来设置x的值。活节点队列中元素的类型是Q N o d e (见程序1 7 - 3 )。这里,当且仅当节点是它的父节点的左孩子时,L C h i l d为t r u e。

程序17-3 类Q N o d e

template

class QNode {

p r i v a t e :

QNode *parent; A d d ( b ) ;

}

template

T MaxLoading(T w[], T c, int n, int bestx[])

{A d d ( 0 ) ; D e l e t e ( E ) ; A d d ( 0 ) ; D e l e t e ( E ) ; 最大收益分枝定界

在对子集树进行最大收益分枝定界搜索时,活节点列表是一个最大优先级队列,其中每个活节点x都有一个相应的重量上限(最大收益)。这个重量上限是节点x 相应的重量加上剩余货箱的总重量,所有的活节点按其重量上限的递减顺序变为E-节点。需要注意的是,如果节点x的重量上限是x . u w e i g h t,则在子树中不可能存在重量超过的节点。另外,当叶节点对应的重量等于它的重量上限时,可以得出结论:在最大收益分枝定界算法中,当某个叶节点成为E-节点并且其他任何活节点都不会帮助我们找到具有更大重量的叶节点时,最优装载的搜索终止。

上述策略可以用两种方法来实现。在第一种方法中,最大优先级队列中的活节点都是互相独立的,因此每个活节点内部必须记录从子集树的根到此节点的路径。一旦找到了最优装载所对应的叶节点,就利用这些路径信息来计算x 值。在第二种方法中,除了把节点加入最大优先队列之外,节点还必须放在另一个独立的树结构中,这个树结构用来表示所生成的子集树的一部分。当找到最大装载之后,就可以沿着路径从叶节点一步一步返回到根,从而计算出x 值。

最大优先队列可用HeapNode 类型的最大堆来表示(见程序1 7 - 5)。uweight 是活节点的重量上限,level 是活节点所在子集树的层,ptr 是指向活节点在子集树中位置的指针。子集树中节点的类型是b b n o d e(见程序1 7 - 5)。节点按u w e i g h t值从最大堆中取出。

程序17-5 bbnode 和HeapNode 类

class bbnode {

p r i v a t e :

bbnode *parent; I n s e r t ( N ) ;

}

template

T MaxLoading(T w[], T c, int n, int bestx[])

{说明

1) 使用最大堆来表示活节点的最大优先队列时,需要预测这个队列的最大长度(程序1 7 - 6

中是1 0 0 0)。为了避免这种预测,可以使用一个基于指针的最大优先队列来取代基于数组的队列,这种表示方法见9 . 4节的左高树。

2) bestw表示当前所有可行节点的重量的最大值,而优先队列中可能有许多其u w e i g h t不超过b e s t w的活节点,因此这些节点不可能帮助我们找到最优的叶节点,这些节点浪费了珍贵的队列空间,并且它们的插入/删除动作也浪费了时间,所以可以将这些节点删除。有一种策略可以减少这种浪费,即在插入某个节点之前检查是否有u w e i g h t < b e s t w。然而,由于b e s t w在算法执行过程中是不断增大的,所以目前插入的节点在以后并不能保证u w e i g h t < b e s t w。另一种更好的方法是在每次b e s t w增大时,删除队列中所有u w e i g h t < b e s e w的节点。这种策略要求删除具有最小u w e i g h t的节点。因此,队列必须支持如下的操作:插入、删除最大节点、删除最小节点。这种优先队列也被称作双端优先队列(double-ended priority queue)。这种队列的数据结构描述见第9章的参考文献。

5.2.2 0/1背包问题

0 / 1背包问题的最大收益分枝定界算法可以由程序1 6 - 6发展而来。可以使用程序1 6 - 6的B o u n d函数来计算活节点N的收益上限u p ,使得以N为根的子树中的任一节点的收益值都不可能超过u p r o f i t。活节点的最大堆使用u p r o f i t作为关键值域,最大堆的每个入口都以H e a p N o d e作为其类型,H e a p N o d e有如下私有成员:uprofit, profit, weight,l e v e l,p t r,其中l e v e l和p t r的定义与装箱问题(见程序1 7 - 5)中的含义相同。对任一节点N,N . p r o f i t是N的收益值,N uprofit是它的收益上限,N. weight 是它对应的重量。b b n o d e类型如程序1 7 - 5中的定义,各节点按其u p r o f i t值从最大堆中取出。

程序1 7 - 7使用了类Knap, 它类似于回溯法中的类K n a p(见程序1 6 - 5)。两个K n a p版本中数据成员之间的区别见程序1 7 - 7:1) bestp 不再是一个成员;2) bestx 是一个指向int 的新成员。新增成员的作用是:当且仅当物品j 包含在最优解中时, b e s t x [ j ] = 1。函数A d d L i v e N o d e用于将新的b b n o d e类型的活节点插入子集树中,同时将H e a p N o d e 类型的活节点插入到最大堆中。这个函数与装箱问题(见程序1 7 - 6)中的对应函数非常类似,因此相应的代码被省略。

程序17-7 0/1背包问题的最大收益分枝定界算法

template

Tp Knap::MaxProfitKnapsack()

{5.2.34 . 2 . 35.2.44 . 2 . 4 n )。旅行路径前缀1 的开销为0 ,即c c = 0 ,并且,r c o st=n i=1M i n O u t [i]。在程序中,bestc 给出了当前能找到的最少的耗费值。初始时,由于没有找到任何旅行路径,因此b e s t c的值被设为N o E d g e。

程序17-9 旅行商问题的最小耗费分枝定界算法

template

T AdjacencyWDigraph::BBTSP(int v[]) {s + + ;

H . I n s e r t ( E ) ; }

else delete [] ;}

else {I n s e r t ( N ) ; }

} 5.2.56 . 2 . 5x [ 1 : s ]

= 0; . . n for (int j = 1; j <= m; j++)

total[j] += B[i][j]; I n s e r t ( N ) ; } else delete [] ;}

delete [] ;} .) {break;}

} while (true);

return bestd;

}

程序1 7 - 1 0首先初始化E-节点为排列树的根,此节点中没有任何电路板,因此有s=0, cd=0,n o w [ i ] = 0(1≤i≤n),x 是整数1到n 的任意排列。接着,程序生成一个整型数组t o t a l,其中total[i] 的值为包含i 的电路板的数目。目前能找到的最优的电路板排列记录在数组bestx 中,对应的密度存储在bestd 中。程序中使用一个do-while 循环来检查每一个E-节点,在每次循环的尾部,将从最小堆中选出具有最小cd 值的节点作为下一个E-节点。如果某个E-节点的cd 值大于等于bestd,则任何剩余的活节点都不能使我们找到密度小于bestd的电路板排列,因此算法终止。

d o - w h i l e循环分两种情况处理E-节点,第一种是处理s = n - 1时的情况,此种情况下,有n - 1个电路板被放置好,E-节点即解空间树中的某个叶节点的父节点。节点对应的密度会被计算出来,如果需要,bested 和bestx 将被更新。在第二种情况中,E-节点有两个或更多的孩子。每当一个孩子节点N生成时,它对应的部分排列( x [ 1 : s + 1 ] )的密度N . c d就会被计算出来,如果N . c d < b

e s t d ,则N被存放在最小优先队列中;如果N . c d≥b e s t d,则它的子树中的所有叶节点对应的密度都满足d e n s i t y≥b e s t d,这就意味着不会有优于b e s t x的排列。

练习

3. 在程序1 7 - 4中增加代码,将指向由函数A d d L i v e N o d e生成的节点的指针存储在一个链表队列中。M a x L o a d i n g 必须利用这些指针信息在程序终止之前删除所有生成的节点。

4. 本节所使用的A d d L i v e N o d e函数直到程序终止前才删除所生成的节点。实际上,没有活动孩子且不产生叶节点的那些节点都可以被立即删除。类似地,在第n 层节点中,若节点没有重量为b e s t w的孩子,则可以立即删除该节点。讨论怎样尽快删除不需要的节点。描述实现这种方法时所涉及的时间/空间变化。你推荐使用上述方法吗?

5. 在程序1 7 - 6中,定义一个b e s t w来记录目前生成的可行节点所对应的重量的最大值。修改程序1 7 - 6,使得如果活节点的重量大于等于b e s t w,则将它加入子集树及最大堆中。此外,还必须增加初始化和更新b e s t w的代码。

6. 只使用一个最大优先队列,来实现用最大收益分枝定界方法求解货箱装船问题,即不要使用程序1 7 - 6中所用到的部分解空间树,而在每个优先队列的节点中都加入通向根节点的路径信息。

7. 修改程序1 7 - 6,把删除b b n o d e类型和H e a p N o d e类型节点的任务放在程序结尾处。

8. 只使用一个最大优先队列,利用最大收益分枝定界法求解0 / 1背包问题,即不必保存一个部分解空间树,所有优先队列中的节点都记录着通往根节点的路径。

9. 修改程序1 7 - 7,使得删除b b n o d e和H e a p N o d e类型的节点的任务放在程序的结尾处执行。

10. 1) 程序1 7 - 8中,若右孩子的u n值大于等于b e s t n,则将它加入最大堆中,如果将条件设为u n > b e s t n,程序能否正确执行呢?为什么?

2) 程序是否将u n≥b e s t n的左孩子加入最大堆中?

3) 修改程序,使得只将u n > b e s t n的节点加入到最大堆和生成的解空间树中。

11. 考察最大完备子图问题的解空间树。对于任意层(第i层)的子树中的节点x,令MinDegree(x) 为x 所包含的顶点的度的最小值。

1) 证明任何以x为根的子树的叶节点都不可能表示一个尺寸超过X . u n=min{ +n-i+1,M i n D e g r e e (X)+1 }的完备子图。

2) 使用以上X . u n的定义重写B B M a x C l i q u e。

3) 比较两种B B M a x C l i q u e版本在运行时间及产生解空间树节点的数目上的不同。

12. 只使用最大优先队列,实现最大完备子图问题的最大收益分枝定界算法。即:不必保存一个部分解空间树,而在每一个

最大优先队的节点内包含通向根的路径。

13. 修改程序1 7 - 8,使得删除b b n o d e和C l i q u e N o d e类型的节点的工作放在程序结尾处执行。

14. 修改程序1 7 - 9,使得s = n - 2的节点不进入优先队列,并且,将当前最优排列放在数组b e s t p中。当下一个E-节点的lcostbestc 时,算法终止。

15. 使用指向父节点的指针来实现部分解空间树,并使用包含l c o s t,c c,r c o s t和p t r(指向解空间树中对应节点的指针)域的优先队列来实现程序1 7 - 9。

16. 写出用F I F O分枝定界方法求解电路板排列问题的代码。代码必须输出最优电路板排列的排列次序及对应的密度。使用合适的数据来测试代码的正确性。

17. 用F I F O分枝定界方法来搜索一种电路板的排列,使得最长的网组的长度最小(参见4章练习1 7)。

18. 使用最小耗费分枝定界法来完成练习1 7。

19. 用最小耗费分枝定界算法求解4章练习1 8的顶点覆盖问题。

20. 用最大收益分枝定界算法求解4章练习1 9的简易最大切割问题。

21. 用最小耗费分枝定界算法求解4章练习2 0的机器设计问题。

22. 用最小耗费分枝定界算法求解4章练习2 1的网络设计问题。

23. 用F I F O分枝定界算法求解4章练习2 2的n -皇后放置问题。

* 24. 用F I F O分枝定界完成4章练习2 3。

* 25. 用F I F O分枝定界完成4章练习2 4。

* 26. 用F I F O分枝定界完成4章练习2 5。

* 27. 用最小耗费分枝定界完成4章练习2 3。

* 28. 用最小耗费分枝定界完成4章练习2 4。

* 29. 用最小耗费分枝定界完成4章练习2 5。

* 30. 用任意的分枝定界方法完成4章的练习2 5。在本练习中,必须把增加活节点的函数以及选择下一个E-节点的函数作为函数的参数。

(说明:本资料是根据《数据结构、算法与应用》(美,Sartaj Sahni著)一书第13-17章编辑、改写的。考虑到因特网传输速度等因素,大部分插图和公式不得不被删除。对于内容不连贯之处,请网友或读者参阅该书,敬请原谅。)

割平面法

题目:割平面法及其数值实现 院系:数理科学与工程学院应用数学系 专业:数学与应用数学 姓名学号:*** 1****** *** 1****** *** 1****** *** 1****** 指导教师:张世涛 日期:2015 年 6 月11 日

整数规划与线性规划有着密不可分的关系,它的一些基本算法的设计都是从相应的线性规划的最优解出发的。整数规划问题与我们的实际生活有着密切的联系,如合成下料问题、建厂问题、背包问题、投资决策问题、旅行商问题、生产顺序表问题等都是求解整数模型中的著名问题。所以要想掌握生活中这些解决问题的方法,研究整数规划是必然的路径。用于解决整数规划的方法主要有割平面法,分支定界法,小规模0-1规划问题的解法,指派问题和匈牙利法。本文重要对整数规划中经常用的割平面法加以介绍及使用Matlab 软件对其数值实现。 割平面法从线性规划问题着手,在利用单纯型法的时候,当约束矩阵中出现分数,给出一种"化分为整"的方法。然后在割平面方法来解决整数线性规划的理论基础上,把"化分为整"的方法进行到底,直到求解出最有整数解。 关键词:最优化;整数规划;割平面法;数值实现;最优解;Matlab软件。 Abstract The integer programming are closely related to the linear programming. Some of the basic algorithms of the former are designed from the optimal solution of the corresponding linear programming. What’s more, our daily life has a close relationship with it as well, such as synthesis problem, plant problem, knapsack problem, investment decision problem, traveling salesman problem and production sequence table problems. They are famous questions in solving integer model. So, to study the integer programming is the inevitable way to master the methods of solving these problems in life. The methods used in solving the integer programming include cutting plane method, branch and bound method, and solving the problem of small-scale 0-1 programming, assignment problem and Hungarian method. In this paper, we introduce the cutting plane method and use Matlab to get its numerical implementation in the integer programming. Cutting plane method, giving us a "integrated" method when we meet the constraint matrix scores in the use of simplex method, starts from the linear programming problem. Then, based on the theory of cutting plane method to solve the integer linear programming, we use “integrated” method until the most integer solution is solved. Keywords:Optimization; Integer programming; Cutting plane method; Numerical implementation; Optimal solution; Matlab software.

运筹学 (1)

期末考试《运筹学》B 卷 一、单项选择题(在下列每题的四个选项中,只有一个选项是符合试题要求的。请把答案填入答题框中相应的题号下。每小题2分,共20分) 1.单纯形迭代中,出基变量在紧接着的下一次迭代中( )立即进基。 A .会 B .不会 C .有可能 D .不一定 2.线性规划的约束条件为 X 1 + X 2 + X 3 = 3 ,2X 1+ 2X 2+ X 4= 4,X i ≥0(i=1-4),则基本可行解是( ) A .(0,0,4, 3) B .(0,0,3,4) C .(2,1,0,-2) D .(3,0,0,-2) 3.普通单纯形法的最小比值定理的应用是为了保证( ) A .使原问题保持可行 B .使对偶问题保持可行 C .逐步消除原问题不可行性 D .逐步消除对偶问题的不可行性 4. 原问题与对偶问题都有可行解,则有( ) A .原问题有最优解,对偶问题可能没有最优解 B .原问题与对偶问题可能都没有最优解 C .可能一个问题有最优解,另一个问题具有无界解 D .原问题与对偶问题都具有最优解 5. 求解整数规划问题的分支定界法中,有( ) A .最大值问题的目标值是各分支的上界 B .最大值问题的目标值是各分支的下界 C .最小值问题的目标值是各分支的上界 D .以上结论都不对 6.在运输方案中出现退化现象,是指数字格的数目 ( ) A .等于 m+n B .等于m+n-1 C .小于m+n-1 D .大于m+n-1 7.若运输问题的单位运价表的某一行元素分别加上一个常数k ,最优调运方案将( )。 A .发生变化 B .不发生变化 C .A 、B 都有可能 D. 都不对 8.在产销平衡运输问题中,设产地为m 个,销地为n 个,那么解中非零 变量的个数( )。 A .不能大于(m+n-1) B .不能小于(m+n-1) C .等于(m+n-1) D .不确定 9.在运输问题中,每次迭代时,如果有某非基变量的检验数等于零,则该运输问题( )。 A .无最优解 B .有无穷最优解 C .有唯一最优解 D .出现退化解 10.动态规划问题中最优策略具有性质:( )。 A .每个阶段的决策都是最优的 B .当前阶段以前的各阶段决策是最优的 C .无论初始状态与初始决策如何,对于先前决策所形成的状态而言,其以后的所有决策应构成最优策略 D .它与初始状态无关 二、判断题(每题1分,共10分)

分支定界法和割平面法

分支定界法和割平面法 在上学期课程中学习的线性规划问题中,有些最优解可能是分数或消失,但现实中某些 具体的问题,常要求最优解必须是整数,这样就有了对于整数规划的研究。 整数规划有以下几种分类:(1)如果整数规划中所有的变量都限制为(非负)整数,就 称为纯整数规划或全整数规划;(2)如果仅一部分变量限制为整数,则称为混合整数规划; (3)整数规划还有一种特殊情形是0-1规划,他的变量取值仅限于0或1。本文就适用于 纯整数线性规划和混合整数线性规划求解的分支定界法和割平面法,做相应的介绍。 一、分支定界法 在求解整数规划是,如果可行域是有界的,首先容易想到的方法就是穷举变量的所有可行的整数组合,然后比较它们的目标函数值以定出最优解。对于小型问题,变量数量很少,可行的整数组合数也是很小时,这个方法是可行的,也是有效的。而对于大型的问题,可行的整数组合数很大时,这种方法就不可取了。所以我们的方法一般是仅检查可行的整数组合的一部分,就能定出最有的整数解。分支定界法就是其中一个。 分枝定界法可用于解纯整数或混合的整数规划问题。在二十世纪六十年代初 由Land Doig和Dakin等人提出。由于这方法灵活且便于用计算机求解,所以现在它已是解整数规划的重要方法。目前已成功地应用于求解生产进度问题、旅行推销员问题、工厂选址问题、背包问题及分配问题等。 设有最大化的整数规划问题A,与它相应的线性规划为问题B,从解问题B开始,若其最优解不符合A的整数条件,那么B的最优目标函数必是A的最优目标函数z*的上界,记作z ;而A的任意可行解的目标函数值将是z*的一个下界z。分枝定界法就是将B的可行域分成子区域再求其最大值的方法。逐步减小z和增大z,最终求到z*。现用下例来说明:例1求解下述整数规划 Max z = 40x「90x2 9X1 7X2 -56 7X1 20X2 - 70 x1,x2 -0 且为整数 解(1)先不考虑整数限制,即解相应的线性规划B,得最优解为: 洛=4.81,x2= 1.82, z 二356 可见它不符合整数条件。这时z是问题A的最优目标函数值z*的上界,记作z。而X1=0, X2=0显然是问题A的一个整数可行解,这时z = 0,是z*的一个下界,记作z,即0w z*< 356。 (2)因为X1X2当前均为非整数,故不满足整数要求,任选一个进行分枝。设选X1进行分枝,于是对原问题增加两个约束条件: x, -〔4.81 丨-4“ 一〔4.811 1 =5 于是可将原问题分解为两个子问题B1和B2 (即两支),给每支增加一个约束条件并不影响问题

分支定界法详解

1、概念: 分支定界算法(Branch and bound,简称为BB、B&B, or BnB)始终围绕着一颗搜索树进行的,我们将原问题看作搜索树的根节点,从这里出发,分支的含义就是将大的问题分割成小的问题。大问题可以看成是搜索树的父节点,那么从大问题分割出来的小问题就是父节点的子节点了。分支的过程就是不断给树增加子节点的过程。而定界就是在分支的过程中检查子问题的上下界,如果子问题不能产生一比当前最优解还要优的解,那么砍掉这一支。直到所有子问题都不能产生一个更优的解时,算法结束。 2、例子: 用BB算法求解下面的整数规划模型 因为求解的是最大化问题,我们不妨设当前的最优解BestV为-INF,表示负无穷。 1.

首先从主问题分出两支子问题: 通过线性松弛求得两个子问题的upper bound为Z_LP1 = 12.75,Z_LP2 = 12.2。由于Z_LP1 和Z_LP2都大于BestV=-INF,说明这两支有搞头,继续往下。 2. 3.

从节点1和节点2两个子问题再次分支,得到如下结果: 子问题3已经不可行,无需再理。子问题4通过线性松弛得到最优解为10,刚好也符合原问题0的所有约束,在该支找到一个可行解,更新BestV = 10。 子问题5通过线性松弛得到upper bound为11.87>当前的BestV = 10,因此子问题5还有戏,待下一次分支。而子问题6得到upper bound为9<当前的BestV = 10,那么从该支下去找到的解也不会变得更好,所以剪掉! 4.

对节点5进行分支,得到: 子问题7不可行,无需再理。子问题8得到一个满足原问题0所有约束的解,但是目标值为4<当前的BestV=10,所以不更新BestV,同时该支下去也不能得到更好的解了。 6.

分支定界算法的MATLAB程序

Linprogdis子程序: function [x,fval,exitflag,output,lambda]=... linprogdis(ifint,f,A,b,Aeq,beq,lb,ub,x0,options) %Title: % 分支定届法求解混合整数线性规划模型 % %初步完成:2002年12月 %最新修订: 2004-03-06 %最新注释:2004-11-20 %数据处理 [t1,t2] = size(b); if t2~=1, b=b';%将b转置为列向量 end %调用线性规划求解 [x,fval,exitflag,output,lambda] = linprog(f,A,b,Aeq,beq,lb,ub,x0,options); if exitflag<=0,%如果线性规划失败,则本求解也失败 return end %得到有整数约束的决策变量的序号 v1=find(ifint==1);%整数变量的index tmp=x(v1);%【整数约束之决策变量】的当前值 if isempty(tmp), %无整数约束,则是一般的线性规划,直接返回即可 return end v2=find(checkint(tmp)==0);%寻找不是整数的index if isempty(v2), %如果整数约束决策变量确实均为整数,则调用结束 return end %第k个决策变量还不是整数解 %注意先处理第1个不满足整数约束的决策变量 k=v1(v2(1)); %分支1:左分支 tmp1=zeros(1,length(f));%线性约束之系数向量 tmp1(k)=1; low=floor(x(k)); %thisA 分支后实际调用线性规划的不等式约束的系数矩阵A %thisb 分支后实际调用线性规划的不等式约束向量b if ifrowinmat([tmp1,low],[A,b])==1 %如果分支的约束已经存在旧的A,b中,则不改变约束 thisA= A; thisb= b;

分枝定界法讲义_代码

第5 章分枝定界 任何美好的事情都有结束的时候。现在我们学习的是本书的最后一章。幸运的是,本章用到的大部分概念在前面各章中已作了介绍。类似于回溯法,分枝定界法在搜索解空间时,也经常使用树形结构来组织解空间(常用的树结构是第1 6章所介绍的子集树和排列树)。然而与回溯法不同的是,回溯算法使用深度优先方法搜索树结构,而分枝定界一般用宽度优先或最小耗费方法来搜索这些树。本章与第1 6章所考察的应用完全相同,因此,可以很容易比较回溯法与分枝定界法的异同。相对而言,分枝定界算法的解空间比回溯法大得多,因此当内存容量有限时,回溯法成功的可能性更大。 算法思想 分枝定界(branch and bound)是另一种系统地搜索解空间的方法,它与回溯法的主要区别在于对E-节点的扩充方式。每个活节点有且仅有一次机会变成E-节点。当一个节点变为E-节点时,则生成从该节点移动一步即可到达的所有新节点。在生成的节点中,抛弃那些不可能导出(最优)可行解的节点,其余节点加入活节点表,然后从表中选择一个节点作为下一个E-节点。从活节点表中取出所选择的节点并进行扩充,直到找到解或活动表为空,扩充过程才结束。 有两种常用的方法可用来选择下一个E-节点(虽然也可能存在其他的方法): 1) 先进先出(F I F O)即从活节点表中取出节点的顺序与加入节点的顺序相同,因此活节点表的性质与队列相同。 2) 最小耗费或最大收益法在这种模式中,每个节点都有一个对应的耗费或收益。如果查找一个具有最小耗费的解,则活节点表可用最小堆来建立,下一个E-节点就是具有最小耗费的活节点;如果希望搜索一个具有最大收益的解,则可用最大堆来构造活节点表,下一个E-节点是具有最大收益的活节点。 例5-1 [迷宫老鼠] 考察图16-3a 给出的迷宫老鼠例子和图1 6 - 1的解空间结构。使用F I F O分枝定界,初始时取(1,1)作为E-节点且活动队列为空。迷宫的位置( 1 , 1)被置为1,以免再次返回到这个位置。(1,1)被扩充,它的相邻节点(1,2)和(2,1)加入到队列中(即活节点表)。为避免再次回到这两个位置,将位置(1,2)和(2,1)置为1。此时迷宫如图1 7 - 1 a所示,E-节点(1,1)被删除。 节点(1,2)从队列中移出并被扩充。检查它的三个相邻节点(见图1 6 - 1的解空间),只有(1,3)是可行的移动(剩余的两个节点是障碍节点),将其加入队列,并把相应的迷宫位置置为1,所得到的迷宫状态如图17-1b 所示。节点(1,2)被删除,而下一个E-节点(2,1)将会被取出,当此节点被展开时,节点(3,1)被加入队列中,节点(3,1)被置为1,节点(2,1)被删除,所得到的迷宫如图17-1c 所示。此时队列中包含(1,3)和(3,1)两个节点。随后节点(1,3)变成下一个E-节点,由于此节点不能到达任何新的节点,所以此节点即被删除,节点(3,1)成为新的E-节点,将队列清空。节点(3,1)展开,(3,2)被加入队列中,而(3,1)被删除。(3,2)变为新的E-节点,展开此节点后,到达节点(3,3),即迷宫的出口。 使用F I F O搜索,总能找出从迷宫入口到出口的最短路径。需要注意的是:利用回溯法找到的路径却不一定是最短路径。有趣的是,程序6 - 11已经给出了利用F I F O分枝定界搜索从迷宫的(1,1)位置到(n,n)位置的最短路径的代码。 例5-2 [0/1背包问题] 下面比较分别利用F I F O分枝定界和最大收益分枝定界方法来解决如下背包问题:n=3, w=[20,15,15], p=[40,25,25], c= 3 0。F I F O分枝定界利用一个队列来记录活节点,节点将按照F I F O顺序从队列中取出;而最大收益分枝定界使用一个最大堆,其中的E-节点按照每个活节点收益值的降序,或是按照活节点任意子树的叶节点所能获得的收益估计值的降序从队列中取出。本例所使用的背包问题与例1 6 . 2相同,并且有相同的解空间树。 使用F I F O分枝定界法搜索,初始时以根节点A作为E-节点,此时活节点队列为空。当节点 A展开时,生成了节点B和C,由于这两个节点都是可行的,因此都被加入活节点队列中,节点A被删除。下一个E-节点是B,展开它并产生了节点D和E,D是不可行的,被删除,而E被加入队列中。下一步节点C成为E-节点,它展开后生成节点F和G,两者都是可行节点,加入队列中。下一个E-节点E生成节点J和K,J不可行而被删除,K是一个可行的叶节点,并产生一个到目前为止可行的解,它的收益值为4 0。 下一个E-节点是F,它产生两个孩子L、M,L代表一个可行的解且其收益值为5 0,M代表另一个收益值为1 5的可行解。G是最后一个E-节点,它的孩子N和O都是可行的。由于活节点队列变为空,因此搜索过程终止,最佳解的收益值为5 0。 可以看到,工作在解空间树上的F I F O分枝定界方法非常象从根节点出发的宽度优先搜索。它们的主要区别是在F I F O

整数规划_分支定界法_MATLAB程序

整数规划分支定界法MATLAB 程序 1.这种方法绝对能都解出答案,而且答案正确function [x,val]=fzdj(n,f,a,b,aeq,beq,lb,ub) x=zeros(n,1); x1=zeros(n,1); m1=2; m2=1; [x1,val1]=linprog(f,a,b,aeq,beq,lb,ub); if (x1==0) x=x1; val=val1; elseif (round(x1)==x1) x=x1; val=val1; else e1={0,a,b,aeq,beq,lb,ub,x1,val1}; e(1,1)={e1}; zl=0; zu=-val1; while (zu~=zl) for c=1:1:m2 if (m1~=2) if (cell2mat(e{m1-1,c}(1))==1) e1={1,[],[],[],[],[],[],[],0}; e(m1,c*2-1)={e1}; e(m1,c*2)={e1}; continue; end; end; x1=cell2mat(e{m1-1,c}(8)); x2=zeros(n,1); s=0; s1=1; s2=1; lb1=cell2mat(e{m1-1,c}(6)); ub1=cell2mat(e{m1-1,c}(7)); lb2=cell2mat(e{m1-1,c}(6)); ub2=cell2mat(e{m1-1,c}(7)); for d=1:1:n if (abs((round(x1(d))-x1(d)))>0.0001)&(s==0) s=1; lb1(d)=fix(x1(d))+1; if (a*lb1<=b) s1=0; end; ub2(d)=fix(x1(d)); if (a*lb2<=b) s2=0; end; end; end; e1={s1,a,b,aeq,beq,lb1,ub1,[],0}; e2={s2,a,b,aeq,beq,lb2,ub2,[],0}; e(m1,c*2-1)={e1}; e(m1,c*2)={e2}; end; m1=m1+1;

分支定界法和割平面法

分支定界法和割平面法 在上学期课程中学习的线性规划问题中,有些最优解可能是分数或消失,但现实中某些具体的问题,常要求最优解必须是整数,这样就有了对于整数规划的研究。 整数规划有以下几种分类:(1)如果整数规划中所有的变量都限制为(非负)整数,就称为纯整数规划或全整数规划;(2)如果仅一部分变量限制为整数,则称为混合整数规划;(3)整数规划还有一种特殊情形是0-1规划,他的变量取值仅限于0或1。本文就适用于纯整数线性规划和混合整数线性规划求解的分支定界法和割平面法,做相应的介绍。 一、分支定界法 在求解整数规划是,如果可行域是有界的,首先容易想到的方法就是穷举变量的所有可行的整数组合,然后比较它们的目标函数值以定出最优解。对于小型问题,变量数量很少,可行的整数组合数也是很小时,这个方法是可行的,也是有效的。而对于大型的问题,可行的整数组合数很大时,这种方法就不可取了。所以我们的方法一般是仅检查可行的整数组合的一部分,就能定出最有的整数解。分支定界法就是其中一个。 分枝定界法可用于解纯整数或混合的整数规划问题。在二十世纪六十年代初由Land Doig 和Dakin 等人提出。由于这方法灵活且便于用计算机求解,所以现在它已是解整数规划的重要方法。目前已成功地应用于求解生产进度问题、旅行推销员问题、工厂选址问题、背包问题及分配问题等。 设有最大化的整数规划问题A ,与它相应的线性规划为问题B ,从解问题B 开始,若其最优解不符合A 的整数条件,那么B 的最优目标函数必是A 的最优目标函数z *的上界,记作z ;而A 的任意可行解的目标函数值将是z *的一个下界z 。分枝定界法就是将B 的可行域分成子区域再求其最大值的方法。逐步减小z 和增大z ,最终求到z *。现用下例来说明: 例1 求解下述整数规划 219040Max x x z += ??? ??≥≥+≤+且为整数0,7020756792 12121x x x x x x 解 (1)先不考虑整数限制,即解相应的线性规划B ,得最优解为: 124.81, 1.82,356 x x z === 可见它不符合整数条件。这时z 是问题A 的最优目标函数值z *的上界,记作z 。而X 1=0,X 2=0显然是问题A 的一个整数可行解,这时0=z ,是z * 的一个下界,记作z ,即0≤z *≤356 。 (2)因为X 1X 2当前均为非整数,故不满足整数要求,任选一个进行分枝。设选X 1进行分枝,于是对原问题增加两个约束条件: [][]114.814, 4.8115 x x ≤=≥+= 于是可将原问题分解为两个子问题B 1和B 2(即两支),给每支增加一个约束条件并不影响问题A 的可行域,不考虑整数条件解问题B 1和 B 2 ,称此为第一次迭代。得到最优解

分枝定界说明

分支定界(branchand bound)算法是一种在问题的解空间树上搜索问题的解的方法。但与回溯算法不同,分支定界算法采用广度优先或最小耗费优先的方法搜索解空间树,并且,在分支定界算法中,每一个活结点只有一次机会成为扩展结点。 利用分支定界算法对问题的解空间树进行搜索,它的搜索策略是: 1.产生当前扩展结点的所有孩子结点; 2.在产生的孩子结点中,抛弃那些不可能产生可行解(或最优解)的结点; 3.将其余的孩子结点加入活结点表; 4.从活结点表中选择下一个活结点作为新的扩展结点。 如此循环,直到找到问题的可行解(最优解)或活结点表为空。 从活结点表中选择下一个活结点作为新的扩展结点,根据选择方式的不同,分支定界算法通常可以分为两种形式: 1.FIFO(First In First Out)分支定界算法: 按照先进先出原则选择下一个活结点作为扩展结点,即从活结点表中取出结点的顺序与加入结点的顺序相同。 2.最小耗费或最大收益分支定界算法: 在这种情况下,每个结点都有一个耗费或收益。如果要查找一个具有最小耗费的解,那么要选择的下一个扩展结点就是活结点表中具有最小耗费的活结点;如果要查找一个具有最大收益的解,那么要选择的下一个扩展结点就是活结点表中具有最大收益的活结点。 又称分支定界搜索法。过程系统综合的一类方法。该法是将原始问题分解,产生一组子问题。分支是将一组解分为几组子解,定界是建立这些子组解的目标函数的边界。如果某一子组的解在这些边界之外,就将这一子组舍弃(剪枝)。

分支定界法原为运筹学中求解整数规划(或混合整数规划)问题的一种方法。用该法寻求整数最优解的效率很高。将该法原理用于过程系统综合可大大减少需要计算的方案数日。 分支定界法的思想是: 首先确定目标值的上下界,边搜索边减掉搜索树的某些支,提高搜索效率。 在竞赛中,我们有时会碰到一些题目,它们既不能通过建立数学模型解决,又没有现成算法可以套用,或者非遍历所有状况才可以得出正确结果。这时,我们就必须采用搜索算法来解决问题。 搜索算法按搜索的方式分有两类,一类是深度优先搜索,一类是广度优先搜索。 我们知道,深度搜索编程简单,程序简洁易懂,空间需求也比较低,但是这种方法的时间复杂度往往是指数级的,倘若不加优化,其时间效率简直无法忍受;而广度优先搜索虽然时间复杂度比前者低一些,但其庞大的空间需求量又往往让人望而却步。 所以,对程序进行优化,就成为搜索算法编程中最关键的一环。 本文所要讨论的便是搜索算法中优化程序的一种基本方法棗“剪枝”。 什么是剪枝 相信刚开始接触搜索算法的人,都做过类似迷宫这样的题目吧。我们在“走迷宫”的时候,一般回溯法思路是这样的: 1、这个方向有路可走,我没走过 2、往这个方向前进 3、是死胡同,往回走,回到上一个路口 4、重复第一步,直到找着出口

分支定界法

整数线性规划之分支定界法 摘要 最优化理论和方法是在上世纪 40 年代末发展成为一门独立的学科。1947年,Dantaig 首先提出求解一般线性规划问题的方法,即单纯形算法,随后随着工业革命、计算机技术的巨大发展,以及信息革命的不断深化,到现在的几十年时间里,它有了很快的发展。目前,求解各种最优化问题的理论研究发展迅速,例如线性规划、非线性规划以及随机规划、非光滑规划、多目标规划、几何规划、整数规划等,各种新的方法也不断涌现,并且在军事、经济、科学技术等方 面应用广泛,成为一门十分活跃的学科。 整数规划(integer programming)是一类要求要求部分或全部决策变量取整数值的数学规划,实际问题中有很多决策变量是必须取整数的。本文主要介绍求解整数线性规划问题的分支定界法及其算法的matlb实现。 关键词:整数线性规划;分支定界法;matlb程序;

1.引言 1.1优化问题发展现状 最优化理论与算法是一个重要的数学分支,它所讨论的问题是怎样在众多的方案中找到一个最优的方案.例如,在工程设计中,选择怎样的设计参数,才能使设计方案既满足要求又能降低成本;在资源分配中,资源有限时怎样分配,才能使分配方案既可以满足各方面的要求,又可以获得最多的收益;在生产计划安排中,怎样设计生产方案才能提高产值和利润;在军事指挥中,确定怎样的最佳作战方案,才能使自己的损失最小,伤敌最多,取得战争的胜利;在我们的生活中,诸如此类问题,到处可见.最优化作为数学的一个分支,为这些问题的解决提供了一些理论基础和求解方法. 最优化是个古老的课题.长期以来,人们一直对最优化问题进行着探讨和研究.在二十世纪四十年代末,Dantzig 提出了单纯形法,有效地解决了线性规划问题,从而最优化成为了一门独立的学科。目前,有关线性规划方面的理论和算法发展得相当完善,但是关于非线性规划问题的理论和算法还有待进一步的研究,实际应用中还有待进一步的完善。传统的非线性全局最优化方法只能求出问题的局部最优解,但由于许多问题的局部最优解不一定是全局最优解,使得传统的非线性最优化方法不能直接成功地应用于求解非线性全局最优化问题。另外,没有一个固定的评判标准来判断得到的局部最优解是否为全局最优解。随着科学技术的发展和计算机计算能力的提高,最优化理论在最近这几年来得到了迅速的发展,涌现出了许多新的算法, 如打洞函数法,填充函数法,lagrangian 乘子函数方法,信赖域方法,虑子方法等。 本文主要介绍求解整数线性规划问题的分支定界法及其算法的matlb实现。 1.2整数线性规划及其数学模型 整数规划主要有以下三大类: (1)全整数规划(all integer programming):所有的决策变量都取整数值,也称为纯整数规划(pure integer programming); (2)混合整数规划(mixed integer programming):仅要求一部分决策变量取整数值; (3)0-1规划(zero-one integer programming):该类问题的决策变量只能取0或1. 本文主要讨论的整数线性规划问题模型为:

运筹学方法总结

一.线性规划 1.问题背景:线性规划是运筹学中研究较早、发展较快、应用广泛、方法较成熟的一个重要分支,它是辅助人 们进行科学管理的一种数学方法.在经济管理、交通运输、工农业生产等经济活动中,提高经济效果是人们不可缺少的要求,而提高经济效果一般通过两种途径:一是技术方面的改进,例如改善生产工艺,使用新设备和新型原材料.二是生产组织与计划的改进,即合理安排人力物力资源. 线性规划所研究的是:在一定条件下,合理安排人力物力等资源,使经济效果达到最好.一般地,求线性目标函数在线性约束条件下的最大值或最小值的问题 2.求解方法: a.单纯形法: 适用的问题:约束条件全部为≤,右边常数全部为非负,对目标函数的系数没有要求。 min z=3x1-2x2 s.t. x1+2x2≤12 2x1+ x2≤18 x1,x2≥0 求解步骤: STEP 0 将线性规划问题标准化 STEP 1 是否有明显的初始基础可行解,如果有,转STEP 3,否则,转STEP 2。 STEP 2 构造辅助问题,用两阶段法求解辅助问题。如果辅助问题最优解的目标函数值大于0,原问题无可行解,算法终止。否则转STEP 3。 STEP 3 写出单纯形表,将基变量在约束条件中的系数消为单位矩阵,将基变量在目标函数中的系数消为0。转STEP 4。 STEP 4 如果所有非基变量的检验数全为负数或0,则已获得最优解,算法终止。否则,选择检验数为正数并且绝对值最大的非基变量为进基变量。转STEP 5。 STEP 5 如果进基变量在约束条件中的系数全为负数或0,目标函数无界,算法终止。否则根据右边常数和正的系数的最小比值,确定离基变量。转STEP 6。 STEP 6 进基变量列和离基变量行交叉的元素称为主元。对单纯形表进行行变换,将主元变为1,将主元所在列的其他元素变为0。转STEP 4。 b.对偶单纯形法: 适用的问题:约束条件中至少有一个是≥,相应的右边常数为非负,目标函数系数全部为非负。 min z=3x1+2x2 s.t. x1+2x2≥12 2x1+ x2≤18 x1,x2≥0 求解步骤: 步骤1 确定原问题(L)的初始基B,使所有检验数,即是对偶可行解,建立初始单纯形表。 步骤2 检查基变量的取值,若≥0,则已得最优解,计算停;否则求确定单纯形表第L行对应的基变量为旋出变量。 步骤3 若所有,则原问题无可行解,计算停;否则,计算确定对应的为旋入变量。 步骤4 以为主元作(L,K)旋转变换,得新的单纯形表,转步骤2。可以证明,按上述方法进行迭代,所得解始终是对偶可行解。 二.运输问题 1.问题背景:一般的运输问题就是要解决把某种产品从若干个产地调运到若干个销地,在每个产 地的供应量与每个销地的需求量已知,并知道各地之间的运输单价的前提下,如何确定一个使得总的运输费用最小的方案。

简单介绍分支界定法与割平面法

缺点: 某些变量要求整数 不能运用到对数,指数函数中 分支界定法: 分枝定界法是一个用途十分广泛的算法,运用这种算法的技巧性很强,不同类型的问题解法也各不相同。分支定界法的基本思想是对有约束条件的最优化问题的所有可行解(数目有限)空间进行搜索。该算法在具体执行时,把全部可行的解空间不断分割为越来越小的子集(称为分支),并为每个子集内的解的值计算一个下界或上界(称为定界)。在每次分支后,对凡是界限超出已知可行解值那些子集不再做进一步分支。这样,解的许多子集(即搜索树上的许多结点)就可以不予考虑了,从而缩小了搜索范围。这一过程一直进行到找出可行解为止,该可行解的值不大于任何子集的界限。 分枝定界法已经成功地应用于求解整数规划问题、生产进度表问题、货郎担问题、选址问题、背包问题以及可行解的数目为有限的许多其它问题 割平面法: 它的基本思想和分枝界定法基本上一致,首先不考虑变量的整数约束,利用单纯形法求解出线性规划的最优解,如果得到的解是整数那么这个最优解就是原来问题的最优解,如果最优解不是整数解,则就用一张平面将原来的含有最优解的非整数点但不包含整数可行解的点的那一部分可行域切割掉,也就是在原来的整数线性规划的基础上增加适当的线性约束不等式,这个约束不等式就叫切割不等式当其取等号时就是割平面了。此后,继续解这个新得到的整数线性规划,如果得到的新最优解是整数,运算就停止,如果不是整数则继续增加适当的线性约束不等式,直到求出的解满足最优整数要求为止。 通过构造一系列平面来切割掉不含有任何整数可行解的部分,最终获得一个具有整数坐标的顶点的可行域,而该顶点恰好是原整数规划的最优解。割平面法的关键在于,如何构造切割不等式,使增加该约束后能达到真正的切割而且没有切割掉任何整数可行解。 单纯形法是从原始问题的一个可行解通过迭代转到另一个可行解,直到检验数满足最优性条件为止。单纯形法是从原始问题的一个可行解通过迭代转到另一个可行解,直到检验数满足最优性条件为止。

分支定界法Matlab程序实现与验证

分支定界法Matlab 程序实现与验证 为了更深入理解分支定界法计算流程,从而决定花费几天时间仔细学习该算法,并编写出该算法的Matlab 计算程序。同时为了后面个人的借鉴学习,编写本文档。在进行分支定界法计算程序编写过程中,通过网络搜索,发现了Matlab2014版之后嵌入了混合整数线性规划求解函数intlinprog,从而也将该函数的使用方法撰写下来。 1 整数规划问题简介 在线性规划问题中,有些最优解可能是分数或小数,但对于某些具体问题,常有要求解答必须是整数的情形(称为整数解)。例如:所求解是机器的台数、完成工作的人数或装货的车数等,分数或小数的解答就不合要求。为了满足整数解的要求,初看起来,似乎只要把已得到的带有分数或小数的解经过“舍入化整”就可以了。但这常常是不行的,因为化整后不见得是可行解;或虽是可行解,但不一定是最优解。因此,对求最优整数解的问题,有必要另行研究。人们称这样的问题为整数规划(Integer Programming,IP),整数规划是最近几十年发展起来的规划论中的一个分支。 整数规划中如果所有的变数都限制为(非负)整数,就称为纯整数规划(Pure Integer Programming,PIP)或称为全整数规划(All Integer Programming,AIP);如果仅一部分变数限制为整数,则称为混合整数计划(Mixed Integer Programming,MIP)。整数规划的一种特殊情形是0-1规划,该规划中变量的取值仅限于0或1,指派问题就是一类典型的0-1规划问题。 现举例说明用前述单纯形法求得的解不能保证是整数最优解。 例1:某厂拟用集装箱托运甲乙两种货物, 每箱的体积、重量、可获利润以及托运所受限制如表1所示。问两种货物各托运多少箱, 可使获得利润为最大? 表1 货物托运示例数据 货物 体积(m3/箱) 重量(百公斤/箱)利润(百元/箱) 甲 5 2 20 乙 4 5 10 托运限制 24(m3) 13百公斤 设1x 、2x 分别为甲、乙两种货物的托运箱数(为非负整数),列该问题的纯 整数规划模型如下: 12max 2010z x x =+

分支定界法

分支定界法 分支定界法,顾名思义,就是按照定好的界进行分支。这里说的分支意思是“剪枝”。剪的枝是问题解空间树的枝。所谓解空间树,即此问题所有解和中间解形成的树型结构,是有序的。常有排列树和子集树之分,举个例子,n个物品的0-1背包问题的解空间树就是子集树(每个物品都可能为0或1),而最短路径问题的解空间树是一颗排列树。 分支定界法一般有两种实现形式:1.优先队列法2.FIFO队列法。这与分支定界的思想无太多本质联系,只是前者在一般情况下能更快的求得问题解。分支定界法要对问题的解空间树进行“剪枝”操作以减少对解空间树的搜索。那么问题是,如何“剪枝”?这就要回答如何定界的问题。在分支定界法中,“界”的作用就是用来阻止对不可行分支的搜索的。当解空间树很深时(叶子节点为解),如果能在前面几层就预先的知道了“此路不通”或者“此路不是最优”而停止此路的继续,这样能大幅度的提高算法效率。如何定界要放入具体问题中考虑,一般可以以“理论最大最小”这个概念来求界。以0-1背包问题为例,设所有物品预先已经按照单位价值量递减排列。在解空间树的第i层(此时正在考虑第i个物品是否应该被放入的时刻),设左子树为放入i物品,右子树为不放i物品。那么在确定左子树的上界的时候有:界=当前价值+i

的价值+MaxValue(背包剩余重量-i物品重量);其中的MaxValue为放i后剩余背包容量能获得的最大价值,应该注意的是此最大价值为理论意义上的最大价值,比如在继续放入p个后(按单位价值量递减),放不下第p+1个,此时应该按(Value[p+1]/Weight[p+1])*(WeightLeft)来计p+1物品的价值,(实际中不可能放入零点几个某物品。。。);右子树的情形类似。 知道了如何定界,那么在实际流程中就要根据当前目标节点的界来剪枝了(是用上界还是下界,具体问题具体分析)。今天准备举个稍微有点挑战的例子---NPC问题中的TSP问题。 在TSP问题中,由于是环路,每个节点都要进出各一次,我们可以将每个节点最小的入度和最小的出度的和累加作为一个下界,这个下界几乎不可能达到!(全部最小出度的和即为下面提到的rcost的初值) 初始时我们创建一个最小堆,表示活节点队列。堆中按照每个节点的下界来划分优先级,下界越小的优先级越高。由于有是要求回路最小值,所以可以先判断此图是否有回路,没有直接返回,有再继续往下做。然后开始解空间树的搜索,广度优先遍历当前点的连通点,用curcost 来存当前的耗费总和,rcost表示当前点到叶子节点最小出度之和,那么一个节点的下界计算为:curcost+rcost-MinOut(当前点);如果此下界小于当前最优值,则将这个连

最全的运筹学复习题及答案

四、把下列线性规划问题化成标准形式: 2、minZ=2x1-x2+2x3 五、按各题要求。建立线性规划数学模型 1、某工厂生产A、B、C三种产品,每种产品的原材料消耗量、机械台时消耗量以及这些资源的限量,单位产品的利润如下表所示:

根据客户订货,三种产品的最低月需要量分别为200,250和100件,最大月销售量分别为250,280和120件。月销售分别为250,280和120件。 问如何安排生产计划,使总利润最大。 2、某建筑工地有一批长度为10米的相同型号的钢筋,今要截成长度为3米的钢筋90根,长度为4米的钢筋60根,问怎样下料,才能使所使用的原材料最省 ? 1. 某运输公司在春运期间需要24小时昼夜加班工作,需要的人员数量如下表所示: 起运时间 服务员数 2—6 6—10 10一14 14—18 18—22 22—2 4 8 10 7 12 4 每个工作人员连续工作八小时,且在时段开始时上班,问如何安排,使得既满足以上要求,又使上班人数 最少?

五、分别用图解法和单纯形法求解下列线性规划问题.并对照指出单纯形迭代的每一步相当 于图解法可行域中的哪一个顶点。

六、用单纯形法求解下列线性规划问题: 七、用大M法求解下列线性规划问题。并指出问题的解属于哪一类。

八、下表为用单纯形法计算时某一步的表格。已知该线性规划的目标函数为maxZ=5x 1+3x 2,约束形式为“≤”,X 3,X 4为松驰变量.表中解代入目标函数后得Z=10 X l X 2 X 3 X 4 —10 b -1 f g X 3 2 C O 1 1/5 X l a d e 1 (1)求表中a ~g 的值 (2)表中给出的解是否为最优解? (1)a=2 b=0 c=0 d=1 e=4/5 f=0 g=-5 (2) 表中给出的解为最优解 第四章 线性规划的对偶理论 五、写出下列线性规划问题的对偶问题 1.minZ=2x 1+2x 2+4x 3

分支定界法

分支定界法 分支定界法(branch and bound)是一种求解整数规划问题的最常用算法。这种方法不但可以求解纯整数规划,还可以求解混合整数规划问题。 基本信息 中文名称:分支定界法 外文名称:branch and bound 用途:整数规划问题 性质:算法 定义 分支定界法(branch and bound)是一种求解整数规划问题的最常用算法。这种方法不但可以求解纯整数规划,还可以求解混合整数规划问题。 算法步骤 第1步:放宽或取消原问题的某些约束条件,如求整数解的条件。如果这时求出的最优解是原问题的可行解,那么这个解就是原问题的最优解,计算结束。否则这个解的目标函数值是原问题的最优解的上界。 第2步:将放宽了某些约束条件的替代问题分成若干子问题,要求各子问题的解集合的并集要包含原问题的所有可行解,然后对每个子问题求最优解。这些子问题的最优解中的最优者若是原问题的可行解,则它就是原问题的最优解,计算结束。否则它的目标函数值就是原问题的一个新的上界。另外,各子问题的最优解中,若有原问题的可行解的,选这些可行解的最大目标函数值,它就是原问题的最优解的一个下界。 第3步:对最优解的目标函数值已小于这个下界的问题,其可行解中必无原问题的最优解,可以放弃。对最优解的目标函数值大于这个下界的子问题,都先保留下来,进入第4步。

第4步:在保留下的所有子问题中,选出最优解的目标函数值最大的一个,重复第1步和第2步。如果已经找到该子问题的最优可行解,那么其目标函数值与前面保留的其他问题在内的所有子问题的可行解中目标函数值最大者,将它作为新的下界,重复第3步,直到求出最优解。

分支定界

1、分支限界法 (1)描述:采用广度优先产生状态空间树的结点,并使用剪枝函数的方法称为分枝限界法。 所谓“分支”是采用广度优先的策略,依次生成扩展结点的所有分支(即:儿子结点)。 所谓“限界”是在结点扩展过程中,计算结点的上界(或下界),边搜索边减掉搜索树的某些分支,从而提高搜索效率。 (2)原理:按照广度优先的原则,一个活结点一旦成为扩展结点(E-结点)R后,算法将依次生成它的全部孩子结点,将那些导致不可行解或导致非最优解的儿子舍弃,其余儿子加入活结点表中。然后,从活结点表中取出一个结点作为当前扩展结点。重复上述结点扩展过程,直至找到问题的解或判定无解为止。 (3)分支限界法与回溯法 1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。 2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。 (4)常见的分支限界法

1)FIFO分支限界法(队列式分支限界法) 基本思想:按照队列先进先出(FIFO)原则选取下一个活结点为扩展结点。 搜索策略:一开始,根结点是唯一的活结点,根结点入队。从活结点队中取出根结点后,作为当前扩展结点。对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的儿子加入活结点队列中。再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,……,直到找到一个解或活结点队列为空为止。 2)LC(least cost)分支限界法(优先队列式分支限界法) 基本思想:为了加速搜索的进程,应采用有效地方式选择活结点进行扩展。按照优先队列中规定的优先级选取优先级最高的结点成为当前扩展结点。 搜索策略:对每一活结点计算一个优先级(某些信息的函数值),并根据这些优先级;从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。再从活结点表中下一个优先级别最高的结点为当前扩展结点,……,直到找到一个解或活结点队列为空为止。 (5)分支限界法搜索应用举例 1)0-1背包问题,当n=3时,w={16,15,15},p={45,25,25},c=30

相关主题
文本预览
相关文档 最新文档