回溯法求0/1背包问题

回溯法求0/1背包问题

给定n件物品和一个容量为c的背包,物品的重量为Wi,其价值为Vi,0/1背包问题是如何选择背包的物品,其中背包的物品是不可分割的,怎样使得背包中的物品价值最大?

#include"stdio.h"
#include"stdlib.h"
int num;//物品数量
double capability;//背包容量
double value[100];//每个物品价值
double weight[100];//每一个物品的重量
double currentWeight=0.0;//当前背包重量
double currentValue=0.0;//当前背包中物品价值
double bestValue=0.0;//当前最优价值
double valuePerThing[100];//单位物品价值
int order[100];//物品编号
int put[100]={0};//装入的物品
int savePut[100]={0};//保存最优值的设置
void sort(){//排序每件物品的单位价值
    int i,j;
    int tempOrder=0;
    double temp=0.0;

    for(i=1;i<=num;i++)
        valuePerThing[i]=value[i]/weight[i];
    for(i=1;i<=num-1;i++)
        for(j=i+1;j<=num;j++){
            if(valuePerThing[i]<valuePerThing[j]){
                temp=valuePerThing[i];
                valuePerThing[i]=valuePerThing[j];
                valuePerThing[j]=temp;
                tempOrder=order[i];
                order[i]=order[j];
                order[j]=tempOrder;
                temp=value[i];
                value[i]=value[j];
                value[j]=temp;
                temp=weight[i];
                weight[i]=weight[j];
                weight[j]=temp;

            }
        }
}


double bound(int i){//确定 上届 
    double leftWeight=capability=currentWeight;
    double b=currentValue;
    while(i<=num&&weight[i]<=leftWeight){
        leftWeight-=weight[i];
        b+=value[i];
        i++;
    }
    if(i<=num)
        b+=value[i]/weight[i]*leftWeight;
    return b;
}
void backtrack(int i){//回溯过程函数 
    if(i>num){
        if(bestValue<currentValue){
            bestValue=currentValue;
            for(int j=0;j<num;j++){
                savePut[j]=put[j];
            }
        }
        return;
    }
    if(currentWeight+weight[i]<=capability){
        currentWeight+=weight[i];
        currentValue+=value[i];
        put[i]=1;
        backtrack(i+1);
        put[i]=0;
        currentWeight-=weight[i];
        currentValue-=value[i];

    }else{

            backtrack(i+1);
    } 
    if(bound(i+1)>bestValue)
        backtrack(i+1);
}
int main(){//主函数 
    int i;
    printf("请输入物品的数量和容量");
    scanf("%d%lf",&num,&capability);
    printf("请输入物品的重量和价值\n");
    for(i=1;i<=num;i++){
        printf("第%d个物品的重量:",i);
        scanf("%lf",&weight[i]);
        printf("价值是:");
        scanf("%lf",&value[i]);
        order[i]=i;
    }

    sort();
    backtrack(1);
    printf("最有价值为:%lf\n",bestValue);
    printf("需要装入的物品编号为:");
    for(i=1;i<=num;i++){
        if(savePut[i]==1){
            printf(" %d ",order[i]);

        }
    }
    printf("\n");
    system("PAUSE");
    return 0;
}
    原文作者:回溯法
    原文地址: https://blog.csdn.net/chr1341901410/article/details/53415154
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞