回溯法 0-1背包问题

回溯法 0-1背包问题一.回溯法回溯法采用的是深度优先策略,回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如

大家好,又见面了,我是你们的朋友全栈君。

一.回溯法

回溯法采用的是深度优先策略,回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。
(1)三个步骤:
    1.针对所给问题,定义问题的解空间;
    2.确定易于搜索的解空间结构;
   3. 以深度优先的方式搜索解空间。
(2)优化方法:
搜索过程使用剪枝函数来为了避免无效的搜索。剪枝函数包括两类:
    1.使用约束函数,剪去不满足约束条件的路径。
    2.使用限界函数,剪去不能得到最优解的路径。

(3)解空间树的类型分为排列树和子集树。

二.0-1背包问题

问题:给定n种物品和一背包。物品i的重量是wi,其价值为pi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

 1 #include <iostream>
 2 using namespace std;
 3  
 4 #define N 100   //默认有99个物品。第一个不使用
 5 int w[N];    //每个物品的重量
 6 int v[N];    //每个物品的价值
 7 int x[N];     //x[i]=1:物品i放入背包,0代表不放入
 8 int n,c;       //n:一共有多少物品,c:背包的最大容量
 9 
10 int CurWeight = 0;  //当前放入背包的物品总重量
11 int CurValue = 0;   //当前放入背包的物品总价值
12 
13 int BestValue = 0;  //最优值;当前的最大价值,初始化为0
14 int BestX[N];       //最优解;BestX[i]=1代表物品i放入背包,0代表不放入
15 
16 /*
17 *回溯函数 参数t表示当前处在第几层做抉择,t=1时表示当前在决定是否将第一个物品放入背包
18 */
19 void backtrack(int t)
20 {
21     //叶子节点,输出结果
22     if(t>n)
23     {
24         //如果找到了一个更优的解
25         if(CurValue>BestValue)
26         {
27             //保存更优的值和解
28             BestValue = CurValue;
29             for(int i=1; i<=n; ++i)
30                 BestX[i] = x[i];
31         }
32     }
33     else
34     {
35         //遍历当前节点的子节点:0 不放入背包,1放入背包
36         for(int i=0; i<=1; ++i)
37         {
38             x[t]=i;
39  
40             if(i==0) //不放入背包
41             {
42                 backtrack(t+1);
43             }
44             else //放入背包
45             {
46                 //约束条件:当前物品是否放的下
47                 if((CurWeight+w[t])<=c)
48                 {
49                     CurWeight += w[t];
50                     CurValue += v[t];
51                     backtrack(t+1);
52                     CurWeight -= w[t];
53                     CurValue -= v[t];
54                 }
55             }
56         }
57     }
58 }
59  
60 int main()
61 {
62  
63     cout<<"请输入物品的个数:"<<endl;
64     cin>>n;
65     cout<<"请输入每个物品的重量及价值(如5 4):"<<endl;
66     for(int i = 1; i <= n; i++)
67     {
68         cin>>w[i]>>v[i];
69     }
70     cout<<"请输入背包的限制容量:"<<endl;
71     cin>>c;
72     
73     backtrack(1);
74     
75     cout<<"最优值是:"<<BestValue<<endl;
76     cout<<"(";
77     for(int i=1;i<=n;i++)
78         cout<<BestX[i]<<" ";
79     cout<<")";
80     return 0;
81 }
 1 #include <iostream>
 2 using namespace std;
 3  
 4 #define N 100   //默认有99个物品。第一个不使用
 5 int w[N];    //每个物品的重量
 6 int v[N];    //每个物品的价值
 7 int x[N];     //x[i]=1:物品i放入背包,0代表不放入
 8 int n,c;       //n:一共有多少物品,c:背包的最大容量
 9 
10 int CurWeight = 0;  //当前放入背包的物品总重量
11 int CurValue = 0;   //当前放入背包的物品总价值
12 
13 int BestValue = 0;  //最优值;当前的最大价值,初始化为0
14 int BestX[N];       //最优解;BestX[i]=1代表物品i放入背包,0代表不放入
15  
16 void input()
17 {
18     cout<<"请输入物品的个数:"<<endl;
19     cin>>n;
20     cout<<"请输入每个物品的重量及价值(如5 4):"<<endl;
21     for(int i = 1; i <= n; i++)
22     {
23         cin>>w[i]>>v[i];
24     }
25     cout<<"请输入背包的容量:"<<endl;
26     cin>>c;
27 }
28 void output()
29 {
30     cout<<"最优值是:"<<BestValue<<endl;
31     cout<<"(";
32     for(int i=1;i<=n;i++)
33         cout<<BestX[i]<<" ";
34     cout<<")";
35  
36 }
37 /*
38 *回溯函数 参数t表示当前处在第几层做抉择,t=1时表示当前在决定是否将第一个物品放入背包
39 */
40 void backtrack(int t,int CurWeight,int CurValue,int rw,int x[])
41 {
42     //初始调用时rw为所有物品重量和 
43     if(t>n)
44     {
45         //如果找到了一个更优的解
46         if(CurWeight==c&&CurValue>BestValue)
47         {
48             //保存更优的值和解
49             BestValue = CurValue;
50             for(int i=1; i<=n; ++i)
51                 BestX[i] = x[i];
52         }
53     }
54     else
55     {
56         //遍历当前节点的子节点:0 不放入背包,1放入背包
57         if(CurWeight+w[t]<=c) //左孩子结点剪枝 
58         {
59             x[t]=1;//选取第i个物品回溯 
60             backtrack(t+1,CurWeight+w[t],CurValue+v[t],rw-w[t],x);
61         }
62         x[t]=0;//不选取第i个物品回溯 
63         if(CurWeight+rw>c)//右孩子结点剪枝 
64         backtrack(t+1,CurWeight,CurValue,rw-w[t],x);        //rw都减去w[t]代表已经考虑过是否选取当前物品,不必再考虑 
65     }
66  
67 }
68  
69 int main()
70 {
71  
72     input();
73     backtrack(1,0,0,11,x);
74     output();
75     return 0;
76 }

 <span role="heading" aria-level="2">回溯法 0-1背包问题

<span role="heading" aria-level="2">回溯法 0-1背包问题

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155436.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • localdate转date时区问题_Date和LocalDate互转「建议收藏」

    localdate转date时区问题_Date和LocalDate互转「建议收藏」一.简述Date对象表示特定的日期和时间,而LocalDate(Java8)对象只包含没有任何时间信息的日期。因此,如果我们只关心日期而不是时间信息,则可以在Date和LocalDate之间进行转换。二.Date转LocalDate如果要将Java.util.Date转换为java.time.LocalDate,可以使用以下步骤:1)将java.util.Date转换为ZonedDateTime。…

    2022年10月3日
    0
  • Vmware Links(转自VMware-land)「建议收藏」

    Vmware Links(转自VMware-land)「建议收藏」这一阵子在专研虚拟机的VSS备份,无意中发现了VMware-land很好的网站,不知道为什么无法访问,难道也被和谐掉了???以下内容是从Google的页面缓存弄出来的,在Google搜索http://vmware-land.com/Vmware_Links.html第一个就是包含了你所知道的和不知道的,关于VMwareESX的方方面面链接地址Backups:Vir…

    2022年10月3日
    0
  • python里for循环用法_python遍历循环

    python里for循环用法_python遍历循环python中使用for循环的方法发布时间:2020-12-0809:35:27来源:亿速云阅读:95作者:小新小编给大家分享一下python中使用for循环的方法,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!python循环方式有两个,一个是while循环,另一个就是for循环,while循环和if条件分支语句类似,即在条件(表达式)为真的情况下,会执行相应的代码块。…

    2022年8月12日
    6
  • Java异或校验_异或校验计算器

    Java异或校验_异或校验计算器Java异或校验今天要用到异或校验,折腾了半天,写下来留作备用。功能是将一串16进制的数进行异或校验,输出校验和。代码:importjava.util.Scanner;/**亦或校验算法*/publicclassChecksum_XOR{@SuppressWarnings(“resource”)publicstaticvoidmain(String

    2022年10月4日
    0
  • 递归算法–斐波那契数列「建议收藏」

    递归算法–斐波那契数列「建议收藏」大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n&amp;lt;=39很容易我们想到使用递归求解:publicclassSolution{publicintFibonacci(intn){if(n==0)return0;if(n==1)…

    2022年9月11日
    1
  • 利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装—免额外安装CUDA和cudnn(适合小白的保姆级教学)[通俗易懂]

    利用Anaconda安装pytorch和paddle深度学习环境+pycharm安装—免额外安装CUDA和cudnn(适合小白的保姆级教学)[通俗易懂]一、英伟达驱动安装与更新显卡驱动程序就是用来驱动显卡的程序,它是硬件所对应的软件。驱动程序即添加到操作系统中的一小块代码,其中包含有关硬件设备的信息。正常有显卡的电脑都是有驱动程序的,但是有的时候驱动可能版本比较低,支持的cuda版本也是比较低的(但是有的人的显卡是比较老的,就不建议更新驱动,这样会导致各种各样的问题,但是搞深度学习还是要用一块好的显卡用来学习,这点我是有血泪教训的,咬咬牙买块好的显卡,把知识学到手,以后的工资可以多赚会很多显卡的钱),英伟达出的30系列的显卡好像只支持cu…

    2022年6月6日
    70

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号