首页 > 其他 > 详细

回溯法解决0-1背包问题

时间:2019-05-31 21:23:18      阅读:108      评论:0      收藏:0      [点我收藏+]

0-1背包问题
【问题描述】
有n种可选物品1,…,n ,放入容量为c的背包内,使装入的物品具有最大效益。
表示
n :物品个数
c :背包容量
p1,p2, …, pn:个体物品效益值
w1,w2, …,wn:个体物品容量

【问题解析】
0-1背包问题的解指:物品1,…,n的一种放法(x1, ···,xn的0/1赋值),使得效益值最大。
假定背包容量不足以装入所有物品:面临选择
【优化原理】无论优化解是否放物品1,优化解对物品2,…,n的放法,相对剩余背包容量,也是优化解。

首先给出所需要的变量:
```
private static int[] p;//物品的价值数组
private static int[] w;//物品的重量数组
private static int c;//最大可以拿的重量
private static int count;//物品的个数

private static int cw;//当前的重量
private static int cp;//当前的价值
static int bestp;//目前最优装载的价值
private static int r;//剩余物品的价值

private static int[] cx;//存放当前解
private static int[] bestx;//存放最终解
```
解空间树:子集树
可行性约束条件:cw + w[t] < c
上界函数:cp + r <= bestp,即如果当前结点满足这个条件时,就可以将该结点的右子树剪去。

public class Zero_One {
private static int[] p;//物品的价值数组
private static int[] w;//物品的重量数组
private static int c;//最大可以拿的重量
private static int count;//物品的个数

private static int cw;//当前的重量
private static int cp;//当前的价值
static int bestp;//目前最优装载的价值
private static int r;//剩余物品的价值

private static int[] cx;//存放当前解
private static int[] bestx;//存放最终解

public static int Loading(int[] ww,int[] pp, int cc) {
    //初始化数据成员,数组下标从1开始
    count = ww.length - 1;
    w = ww;
    p = pp;
    c = cc;
    cw = 0;
    bestp = 0;
    cx = new int[count+1];
    bestx = new int [count+1];

    //初始化r,即剩余最大价格
    for(int i = 1;i<=count;i++) {
        r += p[i];
    }

    //调用回溯法计算
    BackTrack(1);
    return bestp;   
}

/**
 * 回溯
 * @param t
 */
public static void BackTrack(int t) {
    if(t>count) {//到达叶结点
        if(cp>bestp) {
            for(int i = 1;i<=count;i++) {
                bestx[i] = cx[i];
            }

            bestp = cp;
        }
        return;
    }

    r -= p[t];
    if(cw + w[t] <= c) {//搜索左子树
        cx[t] = 1;
        cp += p[t];
        cw += w[t];
        BackTrack(t+1);
        cp -= p[t];//恢复现场
        cw -= w[t];//恢复现场

    }

    if(cp + r >bestp) {//剪枝操作
        cx[t] = 0;//搜索右子树
        BackTrack(t+1);
    }
    r += p[t];//恢复现场
}



public static void main(String[] args) {
    //测试
    int[] w1 = {0,10,20,30,40,50};
    int[] p1 = {0,20,30,65,40,60};
    int c1 = 100;
    Loading(w1,p1,c1);
    System.out.println("最优装载为:" + bestp);
    for(int i =1;i<=count;i++) {
        System.out.print(bestx[i] + " ");
    }           
}
}

 

回溯法解决0-1背包问题

原文:https://www.cnblogs.com/womendouyiyang/p/10957527.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!