• 回 溯 法


    一、(what?)

    二、(why?)

    三、(how?)

    四、典型例题分析:

    例题1:大卖场购物车2——0-1背包问题

    问题分析:

    算法设计:

    图解算法:

     

     

     

     

     

     

     

     

     

     

    伪代码:

    1. double Bound(int i)//计算上界(即已装入物品价值+剩余物品的总价值)
    2. {
    3. int rp=0; //剩余物品为第i~n种物品
    4. while(i<=n)//依次计算剩余物品的价值
    5. {
    6. rp+=v[i];
    7. i++;
    8. }
    9. return cp+rp;//返回上界
    10. }

     

    1. void Backtrack(int t) //t表示当前扩展结点在第t层
    2. {
    3. if(t>n) //已经到达叶子结点
    4. {
    5. for(j=1;j<=n;j++)
    6. {
    7. bestx[j]=x[j];
    8. }
    9. bestp=cp; //保存当前最优解
    10. return ;
    11. }
    12. if(cw+w[t]<=W) //如果满足约束条件则搜索左子树
    13. {
    14. x[t]=1;
    15. cw+=w[t];
    16. cp+=v[t];
    17. Backtrack(t+1);
    18. cw-=w[t];
    19. cp-=v[t];
    20. }
    21. if(Bound(t+1)>bestp) //如果满足限界条件则搜索右子树
    22. {
    23. x[t]=0;
    24. Backtrack(t+1);
    25. }
    26. }

     完整代码:
     

    1. #include
    2. #include
    3. #include
    4. #define M 105
    5. using namespace std;
    6. int i,j,n,W; //n表示n个物品,W表示购物车的容量
    7. double w[M],v[M];//w[i] 表示第i个物品的重量,v[i] 表示第i个物品的价值
    8. bool x[M]; //x[i]表示第i个物品是否放入购物车
    9. double cw; //当前重量
    10. double cp;//当前价值
    11. double bestp;//当前最优价值
    12. bool bestx[M]; //当前最优解
    13. double Bound(int i)//计算上界(即已装入物品价值,剩余物品的总价值)
    14. {
    15. int rp=0;//剩余物品为第i~n种物品
    16. while(i<=n)//一次计算剩余物品的价值
    17. {
    18. rp+=v[i];
    19. i++;
    20. }
    21. return cp+rp;//返回上界
    22. }
    23. void Backtrack(int t)//t表示当前扩展点在第t层
    24. {
    25. if(t>n)//已经到达叶子结点
    26. {
    27. for(j=1;j<=n;j++)
    28. {
    29. bestx[j]=x[j];
    30. }
    31. bestp=cp;//保存当前最优解
    32. return ;
    33. }
    34. if(cw+w[i]<=W)//如果满足条件约束搜索左子树
    35. {
    36. x[t]=1;
    37. cw+=w[t];
    38. cp+=v[t];
    39. Backtrack(t+1);
    40. cw-=w[t];
    41. cp-=v[t];
    42. }
    43. if(Bound(t+1)>bestp)//如果满足限界条件搜索右子树
    44. {
    45. x[t]=0;
    46. Backtrack(t+1);
    47. }
    48. }
    49. void Knapsack(double W,int n)
    50. {
    51. //初始化
    52. cw=0;
    53. cp=0;
    54. bestp=0;
    55. double sumw=0.0;
    56. double sumv=0.0;
    57. for(i=1;i<=n;i++)
    58. {
    59. sumv+=v[i];
    60. sumw+=w[i];
    61. }
    62. if(sumw<=W)
    63. {
    64. bestp=sumv;
    65. cout<<"放入购物车的物品最大价值为:"<
    66. cout<<"所有的物品均放入购物车。";
    67. return;
    68. }
    69. Backtrack(1);
    70. cout<<"放入购物车的物品最大价值为:"<
    71. cout<<"放入购物车的物品序号为:";
    72. for(i=1;i<=n;i++) //输出最优解
    73. {
    74. if(bestx[i]==1)
    75. cout<" ";
    76. }
    77. cout<
    78. }
    79. int main()
    80. {
    81. cout << "请输入物品的个数n:";
    82. cin >> n;
    83. cout << "请输入购物车的容量W:";
    84. cin >> W;
    85. cout << "请依次输入每个物品的重量w和价值v,用空格分开:";
    86. for(i=1;i<=n;i++)
    87. cin>>w[i]>>v[i];
    88. Knapsack(W,n);
    89. return 0;
    90. }

    例题2:

    例题3:

    例题4:

    例题5:

    例题6:

  • 相关阅读:
    response响应,常用方法,分发器重定向,错误提示
    【Bio】基础生物学 - 蛋白质 protein
    #gStore-weekly | SPARQL 解析(上)
    视频怎么制作成gif动画?这个方法试试看
    Python机器视觉--OpenCV入门--OpencCV的安装与图片加载显示
    javaee springMVC session的使用
    8条非常实用的python代码案例,初学者必备知识点
    Python程序员常犯的编码错误(三)
    如何提高加速运行Mac电脑系统缓慢的5种方法教程
    B46 - STM32太阳能充电智能心率监测骑行仪
  • 原文地址:https://blog.csdn.net/qq_51701007/article/details/123963225