首页 > 其他分享 >0-1背包问题 - 回溯法 - 深度搜索

0-1背包问题 - 回溯法 - 深度搜索

时间:2023-05-25 17:04:37浏览次数:33  
标签:cp 背包 int 装入 搜索 回溯 物品 bestp


算法描述:

0-1背包问题是子集选取问题。一般情况下,0-1背包问题是NP难得。0-1背包问题的解空间可用子集树 表示。在搜索解空间的时,只要其左儿子节点是一个可行节点,搜索就进去其左子树(约束条件)。当右子树中可能包含最优解时才进入右子树搜索(限界函数)。否则就将右子树剪去。计算右子树中解的上界的更好方法是将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入物品的一部分而装满背包。由此得到的价值是右子树中解的上界。

例如,对于0-1背包问题的一个实例,n = 4, c = 7, p = [9, 10, 7, 4], w = [3, 5, 2, 1]。 这四个物品的单位重量分别是[3, 2, 3, 5, 4]。依物品单位重量价值递减序装入物品。先装入物品4,然后装入物品3 和 1。装入这三个物品后,剩余的背包容量为1,只能装入物品2的五分之一( 2 * 五分之一 = 1)。由此得到的一个解为x = [1, 0.2(五分之一), 1, 1], 其响应的的价值是22。尽管这不是一个可行解,但可以证明其价值是最优值的上界(限界函数)。因此,对于这个实例,最优值不超过22。

为了计算上界,可先将物品将其单位重量价值从大到小排序。此后只要按照顺序考察个物品即可。Bound()函数为限界函数。

from 计算机算法设计与分析(第四版) 王晓东编著

另外由于排了序,物品的代号改变,无法输出得到最优解时装入了哪些物品。不过可以创建一个类定义属性 id 来实现记录。这个算法中已实现。

算法实现:

#include <bits/stdc++.h>
using namespace std;
class Object
{
public:
    int p;
    int w;
    int id;
};
int n, c, cp, cw, bestp, total_w, total_p;
int x[100], best_x[100];
Object O[100];
void Input()
{
    scanf("%d %d", &n, &c);
    for(int i = 1; i <= n; ++i)
    {
     scanf("%d %d", &O[i].p, &O[i].w);
     O[i].id = i;
    }
}
bool cmp(const Object &a, const Object &b)
{
    return a.p / a.w > b.p / b.w;
}
void Initilize()
{
    cp = cw = total_w = total_p = bestp = 0;
    for(int i = 1; i <= n; ++i)
    {
        total_p += O[i].p;
        total_w = O[i].w;
    }
    //依照物品单位重量价值排序
    sort(O + 1, O + n + 1, cmp);
    //for(int i = 1; i <= n; ++i)
        //cout << O[i].id << endl;
}
int Bound(int i)
{
    int temp_cw = c - cw;
    int temp_cp = cp;
    while(i <= n && temp_cw >= O[i].w)
    {
        temp_cw -= O[i].w;
        temp_cp += O[i].p;
        ++i;
    }
    //装满背包
    if(i <= n)
        temp_cp += O[i].p / O[i].w * temp_cw;
    return temp_cp;


}
void Backtrack(int i)
{
    if(i > n)
    {
        bestp = cp;
        for(int i = 1; i <= n; ++i)
            best_x[i] = x[i];
        return;
    }
    if(cw + O[i].w <= c)
    {
        x[O[i].id] = 1;
        cw += O[i].w;
        cp += O[i].p;
        Backtrack(i + 1);
        cp -= O[i].p;
        cw -= O[i].w;
        x[O[i].id] = 0;
    }
    if(Bound(i + 1) > bestp)
    {
        x[O[i].id] = 0;
        Backtrack(i + 1);
    }
}
void OutPut()
{
    printf("bestp = %d\n", bestp);
    printf("选取的物品为 : \n");
    for(int i = 1; i <= n; ++i)
    {
        if(best_x[i] == 1)
           cout << i << " ";
    }
}
int main()
{
    Input();
    Initilize();
    Backtrack(1);
    OutPut();
}



测试样例:

输入:

4 7
9 3
10 5
7 2
4 1

输出

bestp = 20

所选物品为:

1 3 4

截图:

0-1背包问题 - 回溯法 - 深度搜索_回溯法

标签:cp,背包,int,装入,搜索,回溯,物品,bestp
From: https://blog.51cto.com/u_16129621/6350070

相关文章

  • 装载问题(最优装载问题变形)-回溯法-深度搜索
    问题描述:有n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且∑wi<=c1+c2。问是否有一个合理的装载方案,可将这n个集装箱装上这2艘轮船。如果有,找出一种装载方案。问题分析:如果一个给定装载问题有解,则采用下面的策略可得到最优装载方案。(1)首先将第一艘轮船......
  • 2-3 改写二分搜索算法
    设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。测试数据(自己写的):61234567输出:i=5,j=-16123456-1输出:i=-1,j=......
  • 0-1背包问题详解-动态规划-两种方法
    问题描述:给定n种物品和一背包。物品i的重量为wi,其价值为vi,背包容量为c。问应如何选择装入背包中的物品,使得背入背包的物品的总价值最大?解析:此问题形式化的描述是,给定c>0,wi,vi,1<=i<=n(c为背包容量),要找出一个n元0-1向量(x1,x2,...,xn),xi ∈{0,1},1<=i<=n,使......
  • 衡量搜索相关性
    [Howintheheckdoyoumeasuresearchrelevance?](https://www.reddit.com/r/RedditEng/comments/te0gfz/how_in_the_heck_do_you_measure_search_relevance/)[MeasuringSearchRelevance,Part2:nDCGDeepDive](https://www.reddit.com/r/RedditEng/comments/y6idrl/......
  • 力扣---450. 删除二叉搜索树中的节点
    给定一个二叉搜索树的根节点root和一个值key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。一般来说,删除节点可分为两个步骤:首先找到需要删除的节点;如果找到了,删除它。 示例1: 输入:root=[5,3,6,2,4,nu......
  • 路径总和 leetcode——递归+回溯
    题目leetcode:113代码与解析这道题可以看做leetcode112和leetcode257合体这道题要遍历整棵树,把所有符合条件的路径添加进去,所以不需要返回值递归三部曲:确定参数和返回值要传入当前节点,和总和,不需要返回值确定终止条件如果当前节点没有叶子结点,并且和等于target.那么添加进r......
  • day01【704. 二分查找,35.搜索插入位置 ,27. 移除元素 】
    704.二分查找二分查找理论二分查找是一个时间效率极高的算法,尤其是面对大量的数据时,其查找效率是极高,时间复杂度是log(n)。主要思想就是不断的对半折叠,每次查找都能除去一半的数据量,直到最后将所有不符合条件的结果都去除,只剩下一个符合条件的结果。二分查找需要的条件用于......
  • elasticsearch/es搜索服务器介绍
    目录1、ElasticSearch介绍1.1原理与应用2、ElasticaSearch的的安装使用2.1安装2.2配置文件2.3启动ES2.4head插件安装1、ElasticSearch介绍我们先来看下百度百科的介绍:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulwe......
  • 【IntelliJ IDEA】idea 的全局搜索快捷键ctrl+shift+f 失效的解决方案
    解决方案一:1、新装的idea的快捷键ctrl+shift+f按了没反应,于是很快就想到快捷键冲突了,马上查看五笔和搜狗输入法的快捷键,如下图: 以上两个都是简体和繁体切换的快捷键。把这两个快捷键换了就可以搞定。 解决方案二:2、第二种方案就是在Idea中设置快捷键,如下图:然后按照以下步骤设置:第......
  • 背包问题
    Part101背包每种物品只有一个,只能选或不选表示u[i][j]表示容量为j时,前i个物品总价值的最大值,u[i][j]即为答案v[i]表示第i个物品的价值w[i]表示第i个物品的体积初始化当容量为0时,价值总和为0,即u[i][0]=0;当选择0个物品时,价值总和为0,即u[0][j]=0;递归式\[u......