C语言,回溯法0-1背包问题

来源:互联网 发布:数据挖掘十大经典算法 编辑:程序博客网 时间:2024/05/16 00:56

回溯法0-1背包问题

本文以 http://blog.sina.com.cn/s/blog_690e57390100khgl.html 为主题编写的回溯0-1背包问题

1、问题描述
物品总数量为n,背包容量为v,物品价值分别为value(……),物品重量为weight(…….),求如何存放物品使背包价值最大。

2、回溯算法思路

  • 初始化数据后,我们先从第一个物品存入到背包中,
  • 判断物品是否已经使用完毕。如何使用完,判断是否当前价值量大于原有最大价值量,如果大于将最大价值量替换,标记放入的物品,否则不做修改
  • 随后,我们判断是否物品存入超出了背包总容积,如果没有将背包现
    在容积以及价值量相加,设置标志已放入背包,保存,随后将下一个背包存放测试,跳转到2
  • 第3步内为一直测试二叉树的左子树,当到达最底部左子树后,回溯到上一结点,现存容积与价值量减去当前结点重量与价值量,进行该结点右子树循环查找,直到第2步返回
  • 回溯结束,跳转到主函数输出结果

以下为VC6.0 下所写代码

#include "stdafx.h"#include "stdio.h"#include "stdlib.h"    #include "string.h" typedef struct {int number;       //物品总数量int volume;       //背吧容量int curValue;     //背包现存价值int curVolume;    //背包现存容量int* curBackpack; //背包内存放物品数组,curPackage[i] = 1; 为已   经放入背包中                   //                                  = 0; 为未放入背包中int maxValue;     //背包最大价值量int* lastBackpack;//最优解背包内物品int* goodsValue;  //物品价值数组int* goodsWeight; //物品重量数组}Backpack;Backpack bp;void initBackpack(int v, int n){    bp.number = n;    bp.volume = v;    bp.curValue = 0;    bp.curVolume = 0;    bp.maxValue = 0;    bp.goodsValue = (int*)malloc(bp.number * sizeof(int));    memset(bp.goodsValue, 0, bp.number * (sizeof(int)));    bp.goodsWeight = (int*)malloc(bp.number * sizeof(int));    memset(bp.goodsWeight, 0, bp.number * (sizeof(int)));    bp.curBackpack = (int*)malloc(bp.number * sizeof(int));    memset(bp.curBackpack, 0, bp.number * (sizeof(int)));    bp.lastBackpack = (int*)malloc(bp.number * sizeof(int));    memset(bp.lastBackpack, 0, bp.number * (sizeof(int)));    for(int j=0;j < bp.number;j++){        printf("请输入第%d个物品价值:",(j+1));        scanf("%d",&bp.goodsValue[j]);        printf("请输入第%d个物品重量:",(j+1));        scanf("%d",&bp.goodsWeight[j]);    }}void backTrace(int position){    if((position+1) > bp.number){        //当物品全部测试后,查看最大价值量,如何新的价值量大于上一次价值量        //替换掉,并记忆存放的物品        if(bp.curValue > bp.maxValue){            bp.maxValue = bp.curValue;                  for(int i=0;i < bp.number;i++){                bp.lastBackpack[i] = bp.curBackpack[i];            }        }        return;    }    //需要通过二叉树图一步步了解回溯    if((bp.curVolume + bp.goodsWeight[position]) <= bp.volume){        bp.curVolume += bp.goodsWeight[position];        bp.curValue += bp.goodsValue[position];        bp.curBackpack[position] = 1;        backTrace(position+1);        bp.curVolume -= bp.goodsWeight[position];        bp.curValue -= bp.goodsValue[position];    }    bp.curBackpack[position] = 0;    backTrace(position+1);}int main(int argc, char* argv[]){    int volume,number;    printf("请输入背包容量:");    scanf("%d",&volume);    printf("请输入物品数量:");    scanf("%d",&number);    initBackpack(volume, number);    backTrace(0);    if(bp.maxValue != 0){        printf("背包最大价值数为:%d\n",bp.maxValue);        printf("背包内存放的物品为:");        for(int i=0;i < bp.number;i++){            if(bp.lastBackpack[i] == 1){                printf("第%d个物品;",(i+1));            }        }        printf("\n");    }else{        printf("\n无最优解\n");    }    return 0;}

声明

本文以开头博客为参考,将算法进行重新编写了下,如有异议可留言。本文为作者第一篇博文,如有错误之处,请留言指出,谢谢!

0 0
原创粉丝点击