0-1背包问题

来源:互联网 发布:paxos算法和zookeeper 编辑:程序博客网 时间:2024/06/08 02:26
#include "stdio.h"#include "stdlib.h"#define MAX 10int n;  //物品数int c;  //背包容量int bestv = 0;  //背包中所装物品的最大价值int cw = 0;  //当前已装重量int cv = 0;   //当前背包内所装物品的价值int x[MAX];  //解向量typedef struct Item{    int w;  //物品重量    int v;  //物品价值    float vDw;  //单位重量价值}Item;Item item[MAX];  //物品int cmp(const void *item1, const void *item2)  //按物品单位重量价值降序{    if((*(Item *)item1).vDw < (*(Item *)item2).vDw)        return 1;    return 0;}//计算上界int bound(int i){    int cv1 = cv;    int cleft = c - cw;   //背包剩余容量    while(i<n && item[i].w<=cleft)  //当物品可装入    {        cv1 += item[i].v;  //当前背包所装物品价值        cleft -= item[i].w;  //剩余容量减少        i++;    }    if(i<n)  //如果没有装满        cv1 += item[i].v*cleft/item[i].w;  //只装入一部分    return cv1;}//搜素到第i个物品void backtrack(int i){    if(i>=n) //如果搜索到叶结点    {        bestv = cv;          return;    }    if(cw+item[i].w<=c) //如果当前所装重量+下一个物品重量<=背包容量,搜索左子树    {        cv += item[i].v;  //当前背包所装物品价值增大        cw += item[i].w;  //当前背包所装物品重量增大        x[i] = 1;        backtrack(i+1);   //检查下一个物品        cv -= item[i].v;  //返回上一层        cw -= item[i].w;    }    if(bound(i+1)>bestv)  //如果上界>当前最优解,则可能产生最优解,搜素右子树    {        x[i] = 0;        backtrack(i+1);   //检查下一个物品    }}void knapsack(int w[], int v[], int n1, int c1){    n = n1;    c = c1;    int i;    int tw = 0;    int tv = 0;    for(i=0; i<n; i++)    {        item[i].w = w[i];        item[i].v = v[i];        item[i].vDw = v[i]/w[i];        tw += item[i].w;        tv += item[i].v;    }    if(tw<=c)    {        printf("全部物品都被装入,总价值为:%d\n", tv);        return;    }    qsort(item, n, sizeof(Item), cmp); //按物品单位重量价值降序    backtrack(0);}int main(){    int n1 = 4;    int c1 = 7;    int w[] = {3, 5,  2, 1};  //物品重量数组    int v[] = {9, 10, 7 ,4};  //物品价值数组    knapsack(w, v, n1, c1);    printf("背包容量为:%d\n", c);    printf("物品重量分别为:");    int i;    for(i=0; i<n; i++)        printf("%d\t", item[i].w);    printf("\n");    printf("物品价值分别为:");    for(i=0; i<n; i++)        printf("%d\t", item[i].v);    printf("\n");    printf("被装入的物品为:\n");    for(i=0; i<n; i++)        if(x[i])            printf("物品%d(重%d,价值%d)\n", i+1, item[i].w, item[i].v);    printf("\n");    printf("此时背包中所装物品的总价值为:%d\n", bestv);    return 0;}

这里写图片描述

0 0
原创粉丝点击