当前位置:   article > 正文

0-1背包问题回溯法求解_背包问题的解空间树

背包问题的解空间树

1、树形结构的应用

当需要求解的问题是从N个元素所构成的全集U中找寻满足问题条件的子集时,相应的解空间树称为子集树,在对子集树进行深度优先遍历时储存所经过边的数值,1表示包含该元素,0表示不包含改元素,当遍历到叶子节点时输出这由0与1组成且有N位的字符串,这样一来深度优先遍历完这棵树就能得到其全集U的所有子集,也是求解0-1背包问题会遇到的所有情况。

 

2、回溯法求解思想

我们在用深度优先搜索子集树时并不是非要遍历完每一种情况,在遍历途中利用剪枝条件可以减少代码语句执行次数,回溯法就是在搜索最优解的途中避免无效搜索的一种优化算法。

3、具体代码和现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. const int N=10;
  4. const int bag=N*2;
  5. struct goods{
  6. int w;
  7. int v;
  8. }g[N];
  9. int max_value=0;
  10. int a[N],r[N+1],x[N];
  11. int huisu(int count,int now_v,int now_w);
  12. int main(){
  13. int i;
  14. for (i = 0; i < N; i++) {
  15. g[i].v = rand() % 5 + 1;
  16. g[i].w = rand() % 5 + 1;
  17. printf("物品%d,价值%d,重量%d\n", i, g[i].v, g[i].w);
  18. }
  19. r[N] = 0;
  20. for (i = N - 1; i >= 0; i--) {
  21. r[i] = r[i + 1] + g[i].v;
  22. }
  23. int maxv = huisu(0, 0, 0);
  24. printf("装入的物品是:\n");
  25. int w=0;
  26. for(int i=N-1;i>=0;i--){
  27. if(x[i]==1){
  28. printf("%d ",i);
  29. }
  30. }
  31. printf("\n能获得的最大价值为:%d", maxv);
  32. return 0;
  33. }
  34. int huisu(int count,int now_v,int now_w)
  35. {
  36. if(count==N){
  37. if(now_w<=bag&&now_v>max_value){
  38. max_value=now_v;
  39. for(int j=0;j<N;j++){
  40. x[j]=a[j];
  41. }
  42. }
  43. }
  44. else{
  45. for(int i=0;i<=1;i++){
  46. a[count]=i;
  47. now_v=now_v+g[count].v*i;
  48. now_w=now_w+g[count].w*i;
  49. if(now_w<=bag&&now_v+r[count+1]>=max_value)
  50. huisu(count+1,now_v,now_w);
  51. }
  52. }
  53. return max_value;
  54. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/333073?site
推荐阅读
相关标签
  

闽ICP备14008679号