0-1背包问题

来源:互联网 发布:linux安装两个mysql 编辑:程序博客网 时间:2024/06/10 20:25
#include "cstdio"#include "queue"#define MAX 20   #define INF 999using namespace std;    int n;  //物品数量float w[MAX];  //物品重量数组float c;  //背包容量float nowc;  //当前背包内物品重量float nowp;  //当前背包内物品价值int x[MAX];  //解向量float bestp = 0;struct Item{    float weight;  //重量    float value;   //价值    float vDw;   //单位重量价值};int cmp(const void *item1, const void *item2)  //按单位重量价值降序{    if((*(Item *)item1).vDw < (*(Item *)item2).vDw)        return 1;    else        return 0;}Item item[MAX];struct Node{    float upvalue;  //价值上界    int level;  //结点所在层    float cp;   //当前价值    float cw;  //当前重量    //按价值上界建立优先队列,价值上界大的结点先出队列    bool operator < (const Node &nod) const    {        if(upvalue > nod.upvalue)            return 1;        else            return 0;    }};priority_queue<Node> pq;void EnQueue(float upv, float cp, float cw, int le){    Node node;    node.upvalue = upv;    node.level = le;    node.cp = cp;    node.cw = cw;    pq.push(node);}//计算结点所相应价值的上界float bound(int i)  {    float cleft = c - nowc;  //背包剩余容量    float nowv = nowp;  //当前背包内物品价值    int j;    //以物品单位重量价值递减序装剩余容量    while(i<n && item[i].weight<=cleft)  //如果该物品还装得进去    {        cleft -= item[i].weight;  //剩余容量减少        nowv += item[i].value;     //当前背包内物品价值增加        i++;    }    if(i<n)  //将背包填满        nowv += (item[i].value / item[i].weight * cleft);    return nowv;}float maxKnapsack(){    Node node;  //扩展结点    nowc = 0;  //当前背包内物品重量    nowp = 0;  //当前背包内所装物品价值    int i = 0;  //当前结点所在层    float up = bound(0);  //计算上界    while(i!=n)    {        if(nowc + item[i].weight <= c)//如果当前物品还装得进去,搜索左子树        {            if(nowp+item[i].value > bestp) //更改最优价值                bestp = nowp+item[i].value;            EnQueue(up, nowp+item[i].value, nowc+item[i].weight, i+1);//入队列            x[i] = 1;        }        up = bound(i+1);  //计算上界        if(up >= bestp) //如果上界不小于当前最优价值,可能产生最优价值,搜索右子树        {            EnQueue(up, nowp, nowc, i+1);//入队列            x[i] = 0;        }        node = pq.top();  //取下一个扩展结点        pq.pop();        nowc = node.cw;        nowp = node.cp;        i = node.level;    }    return bestp;}float knapsack(float weight[], float value[], int n1, int c1){    n = n1;    c = c1;    int i;    for(i=0; i<n; i++)    {        item[i].weight = weight[i];        item[i].value = value[i];        item[i].vDw = value[i]/weight[i];    }    qsort(item, n, sizeof(Item), cmp);    return maxKnapsack();}int main(){    float c1 = 30;    int n1 = 3;    float weight[] = {16, 15, 15};    float value[] = {45, 25, 25};    float sum = knapsack(weight, value, n1, c1);    printf("背包容量为:%.1f\n", c);    printf("物品为(重量,价值):\n");    int i;    for(i=0; i<n; i++)        printf("(%.1f, %.1f)\t", item[i].weight, item[i].value);    printf("\n");    printf("背包内所装物品的最大价值为:%.1f\n", sum);    printf("最优解为:\n");    for(i=0; i<n; i++)        printf("%d ", x[i]);    printf("\n");    return 0;}

这里写图片描述

0 0