分枝界限法

回溯法:求出解空间中满足约束条件的所有解。

分支界限法:找出满足约束条件的一个解。

搜索方式:回溯法使用深度优先的方式,而分支界限法使用广度优先或最小耗费的方式搜索解空间。

1. 单源最短路径问题:

问题描述:在有向图中,求出源顶点 s 到 目的顶点的最短路径。

解决办法:使用优先队列式的分支界定法。

算法描述:

        1. 使用最小堆MinHeap来存储活结点列表,初始时MinHeap={ Node }, Node.indx = s,  Node.len = 0.
        2. 使用 dist[1...MaxNode] 来存储s到最各结点的最小距离,初始时 dist[1...MaxNode] = Inf, 但是 dist[s] = 0.
        3. 循环以下操作直到 MinHeap为空:
                    取MinHeap堆顶元素E.
                   针对 i = 1 ... MaxNode:
                            若 adj[ E.indx ][ i ] < Inf && E.len + adj[ E.indx ][ i ] < dist[ i ], 则:     // [这里是剪枝的条件]
                                      dist[ i ] = E.length + adj[ E.indx ][ j ]
                                      pre[ i ] = E.indx
                                      Node={"indx":i, "len":dist[i]}, 将Node 加入堆MinHeap中,  即扩展堆顶的结点。   
python 代码如下:








2. 0-1背包:

( 0-1背包的分枝界定算法法类似于A*算法。)

输入:N个物品重量、价值。 背包重量: W.

算法步骤:

         1. 计算出N个物品的单位价值,按单位价值排序。设排序后N个物品的重量: w1, w2, ..., wN;N个物品的价值:v1, v2, ..., vN。

         2. 设初始重量w=0, 初始价值v=0.

         3. 初始化最大堆的结点:{w=0,v=0, candidate_indx = 1, upbenefit = v + (W-w)*(v1/w1)}。

         4. 对于最大堆的堆顶( upbenefit 最大者在堆顶 )进行扩展:

                       设最大堆顶为:{w_cur, v_cur, candidate_indx, upbenefit }。

                       若:

                       a.  candidate_indx == N+1, 即堆顶为解空间树的叶子节点且目标函数值upbenefit最大,即求得最优解。

                       b. 若 w[ candidate_indx ] > W - w_cur, 即候选节点重量超出背包剩下容量, 放弃此堆顶。

                       c. 若 w [ candidate_indx ] <= W - w_cur, 扩展此候选节点:

                                         删除堆顶,将堆顶进行扩展 并 将扩展后的两个节点加入最大堆( upbenefit )中。

                                        1) 将candidate_indx 节点加入背包中:

                                             在堆中加一个节点:{ w_cur + w[ candidate_indx ], v_cur + v[ candidate_indx ], candidate_indx + 1, upbenefit = w_cur + w[ candidate_indx ] + (W-w_cur-w[candidate_indx]) * ( v[candidate_indx + 1] / w[candidate_indx] ) }

                                             即:将当前候选节点加入背包中,并计算背包的重量、价值、及 可能的最大值。

                                        2) 不加 candidate_indx 节点: 

                                             在堆中加一个节点:{ w, v, candidate_indx+1, v + (W-w)*( v[candidate_indx + 1] / w[candidate_indx] ) }

 上述算法中,upbenefit 为当前选择下,系统可能的最大价值。即已经选择物品的价值v + 未选择物品中单位价值最大值 x 剩余空间。

 堆中每个节点代表了一种背包方案。


示例:

假设有4个物品,其重量分别为(4, 7, 5, 3),价值分别为(40, 42, 25, 12),背包容量W=10。

其执行过程如下图所示:



上面的解空间树中:

w代表背包当前重量,v表示背包当前价值,ub代表在该节点代表的方案下背包最大可能价值。


python代码如下:







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值