0-1背包问题

来源:互联网 发布:会计软件 免费 编辑:程序博客网 时间:2024/06/07 04:02

代码:

#include <stdio.h>#include <stdlib.h>#include <memory.h>#include <string.h>#define DEBUG //调试预处理标记int * pValue = NULL; //物品的价值int * pWeight = NULL;//物品的重量int counts = 0;      //物品的个数int *realSolution = NULL; //存放最终的解int *testSolution = NULL; //存放每次走得路径所得的解/*计算在前k-1件物品已经做出决策的前提下,考虑可能达到的最大的效益值,返回一个上界,  其中,cp代表背包中当前的价值,cw代表当前的重量,k代表是考虑第几个物品,m代表背包的最大容量*/float BoundFound(int cp, int cw, int k, int m){    int i = k;    int c = cw;    float b = (float)cp;    while (i<=counts)    {        c += pWeight[i];        if (c<m)        {            b += pValue[i];        }        else        {            //return (b+(1-(float)(c-m)/pWeight[i])*(pValue[i]));            b += (1-(float)(c-m)/pWeight[i])*(pValue[i]);#ifdef DEBUG            printf("b = %f\n",b);#endif            return b;        }        i++;    }#ifdef DEBUG    printf("b = %f\n",b);#endif    return b;}//m为背包的容量void BackKnap(int m){    int currentWeight = 0;//当前重量    int currentValue = 0;//当前价值    int k = 1;    int finalValue = -1;//最终重量    while(true)    {        /*        int counts = 0;      //物品的个数        int * pWeight = NULL;//物品的重量        m为背包的容量        */#ifdef DEBUG        printf("currentValue=%d,currentWeight=%d,k=%d,finalValue=%d\n",currentValue,currentWeight,k,finalValue);#endif // DEBUG        while(k<=counts && (currentWeight + pWeight[k] <= m))        {            testSolution[k] = 1;//存放每次走得路径所得的解            currentWeight += pWeight[k];            currentValue += pValue[k];            k++;        }        if (k>counts)        {            finalValue = currentValue;            k = counts;            /*            原型:void *memmove( void* dest, const void* src, size_t count );            头文件:<string.h>            功能:由src所指内存区域复制count个字节到dest所指内存区域。            */            memmove((void *)realSolution, (void *)testSolution, (counts+1) * sizeof(int));        }        else        {            testSolution[k] = 0;        }        //如果发现这样的一条路径走得最好结果也没有我现在的结果好,则果断要求回溯        //剩余物品的最优价值是否更优#ifdef DEBUG        printf("currentValue=%d,currentWeight=%d,k=%d,finalValue=%d\n",currentValue,currentWeight,k,finalValue);#endif // DEBUG        while (BoundFound(currentValue, currentWeight, k+1, m) <= finalValue)        {            while((testSolution[k] != 1) && (k != 0)) k--;            if (k==0)            {                return ;            }#ifdef DEBUG            for (int i = 1; i<=counts; i++)            {                printf("testSolution[%d]=%d ",i,testSolution[i]);            }            printf("\n");#endif // DEBUG            testSolution[k] = 0;            currentWeight -= pWeight[k];            currentValue -= pValue[k];#ifdef DEBUG            for (int i = 1; i<=counts; i++)            {                printf("testSolution[%d]=%d ",i,testSolution[i]);            }            printf("\n");#endif // DEBUG        }        k++;    }}int main(){    printf("please input the counts of packages:");    scanf("%d", &counts);    printf("please input the volumn of the bag:");    int m = 0;    scanf("%d", &m);    pWeight = (int *)malloc((counts+1) * sizeof(int));//物品的重量    /*    void *memset(void *s, int ch, size_t n);    函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。    memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法    */    memset((void*)pWeight, 0, sizeof(int)* (counts+1));    for(int i = 1; i <= counts; i++)//输入counts个数的背包重量    {        printf("please input the weight of the %dth package:", i);        scanf("%d", pWeight + i);    }    pValue = (int *)malloc((counts+1) * sizeof(int));    /*    void *memset(void *s, int ch, size_t n);    函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。    memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法    */    memset((void*)pValue, 0, sizeof(int) * (counts+1));    for(int i = 1; i <= counts; i++)//输入counts个数的背包价值    {        printf("please input the value of the %dth package:", i);        scanf("%d", pValue + i);    }    realSolution = (int *)malloc((counts+1) * sizeof(int));//存放最终的解    memset((void*)realSolution, 0, sizeof(int) * (counts+1));    testSolution = (int *)malloc((counts+1) * sizeof(int));//存放每次走得路径所得的解    memset((void*)testSolution, 0, sizeof(int) * (counts+1));    BackKnap(m);//计算最大价值    printf("the best reslut is choosing ");    int maximunValue = 0;//最大背包价值    for (int i = 1; i<=counts; i++)    {        if (realSolution[i] == 1)        {            maximunValue += pValue[i];            printf("the %dth package  ", i);        }    }    printf("\nand the maximun value is %d\n",maximunValue);    return 0;}

运行:

please input the counts of packages:5please input the volumn of the bag:18please input the weight of the 1th package:4please input the weight of the 2th package:8please input the weight of the 3th package:9please input the weight of the 4th package:7please input the weight of the 5th package:3please input the value of the 1th package:5please input the value of the 2th package:9please input the value of the 3th package:7please input the value of the 4th package:6please input the value of the 5th package:2currentValue=0,currentWeight=0,k=1,finalValue=-1currentValue=14,currentWeight=12,k=3,finalValue=-1b = 19.142857currentValue=14,currentWeight=12,k=4,finalValue=-1currentValue=14,currentWeight=12,k=4,finalValue=-1b = 16.000000currentValue=14,currentWeight=12,k=5,finalValue=-1currentValue=16,currentWeight=15,k=5,finalValue=16b = 16.000000testSolution[1]=1 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=1testSolution[1]=1 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 14.000000testSolution[1]=1 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0testSolution[1]=1 testSolution[2]=0 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 16.285715currentValue=5,currentWeight=4,k=3,finalValue=16currentValue=12,currentWeight=13,k=4,finalValue=16b = 14.000000testSolution[1]=1 testSolution[2]=0 testSolution[3]=1 testSolution[4]=0 testSolution[5]=0testSolution[1]=1 testSolution[2]=0 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 13.000000testSolution[1]=1 testSolution[2]=0 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0testSolution[1]=0 testSolution[2]=0 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 16.857143currentValue=0,currentWeight=0,k=2,finalValue=16currentValue=16,currentWeight=17,k=4,finalValue=16b = 16.666666currentValue=16,currentWeight=17,k=5,finalValue=16currentValue=16,currentWeight=17,k=5,finalValue=16b = 16.000000testSolution[1]=0 testSolution[2]=1 testSolution[3]=1 testSolution[4]=0 testSolution[5]=0testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 17.000000currentValue=9,currentWeight=8,k=4,finalValue=16currentValue=17,currentWeight=18,k=5,finalValue=17b = 17.000000testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=1 testSolution[5]=1testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=1 testSolution[5]=0b = 15.000000testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=1 testSolution[5]=0testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 11.000000testSolution[1]=0 testSolution[2]=1 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0testSolution[1]=0 testSolution[2]=0 testSolution[3]=0 testSolution[4]=0 testSolution[5]=0b = 14.333333the best reslut is choosing the 2th package  the 4th package  the 5th packageand the maximun value is 17
0 0
原创粉丝点击