数据结构-五大基本算法-分支限定算法

1.分支限定法:

特点:1.每一个节点,都有2种可能 “存在”、“不存在”

2. 每一次的 V/W 取的都是下一个放入节点的 V/W

3.取叶子节点 最大 的值,就是最优解

例如:0-1背包问题,假设有4个物品,其重量分别为 (4,7,5,3),价值分别为(40,42,25,12) 背包容量W= 10,首先,将给定物品按单位价值从大到小排序,结果如下:

物品      重量(w)价值(v)价值/重量(v/w)
144010
27426
35255
43124

最终得到 : 9, 7, 3 这三个叶子节点,其中 9 节点的ub 最大 所以也是最优解

流程分析:

节点1: 不放入第一个物品,W = 0 V=0, ub = 100

节点2: 放入 第一个物品,W = 4, v = 0, ub = 76

节点 3:不放入 第二个物品,W = 0, V=0 ub = 60

节点4 :放入 第二个物品,重量超出!

节点5: 不放入 第三个物品,此时背包中只有第一个物品,W = 4 v = 40

ub 70 = 40 + (10- 4[节点1 的重量 ] = 6 ) x 5 [节点3的v/w]

节点6 :放入第三个物品 ,W = 4+5 = 9 V = 40+25 = 65

ub 69 = 65 + (10-9 = 1) x 4

节点 7 :不放入 第四个物品, 此时背包中只有第一个物品,W = 4 v = 40

ub 64 = 40 + (10-4 = 6) x 4

节点8 : 放入第四个物品,此时背包中有1,3 两个物品 ,加上第四个物品的重量,W = 12 超出!

节点9 : 不放入第四个物品,背包中有 1,3 两个物品 w = 9, v = 65

ub 65 = 65 + (10-9 =1) x 0

代码实现:

/**
 * @Author wuxiaotian
 * @Date 2021/8/24 19:30
 * @Version C1.4
 */
public class Test02 {
    int[] w = new int[] {40,42,25,12};  //每个物品的重量
    int[] x = new int[] {0, 0, 0,0};   //x[i]=1代表物品i放入背包,0代表不放入

    int CurValue = 0;  //当前放入背包的物品总重量

    int BestValue = 0;  //最优值;当前的最大价值,初始化为0
    int[] BestX = new int[4];       //最优解;BestX[i]=1代表物品i放入背包,0代表不放入
    int N = BestX.length; // 容量
    int C = 100; // 期望值

    //t = 0 to N-1
    void backtrack(int t) {
        //叶子节点,输出结果
        if (t > N - 1) {
            //如果找到了一个更优的解
            if (CurValue > BestValue) {
                //保存更优的值和解
                BestValue = CurValue;
                for (int i = 0; i < N; ++i) {
                    BestX[i] = x[i];
                }

            }
        } else {
            //遍历当前节点的子节点:0 不放入背包,1放入背包
            for (int i = 0; i <= 1; ++i) {
                x[t] = i;
                //不放入背包
                if (i == 0) {
                    backtrack(t + 1);
                }
                //放入背包
                else {
                    //约束条件:放的下
                    if ((CurValue + w[t]) <= C) {
                        CurValue += w[t];
                        backtrack(t + 1);
                        CurValue -= w[t];
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Test02 test2 = new Test02();
        test2.backtrack(0);

        for (int i = 0; i < 4; i++) {
            System.out.println(test2.BestX[i]);
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值