视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
用分支限界求解0-1背包问题
2025-09-30 08:52:11 责编:小OO
文档
实验题目:用分支限界求解0-1背包问题

物品个数n=4,背包容量c=7,价值向量p={9 ,10,7,4},重量向量w={3,5,2,1}请求出最优的解及其目标函数值。

#include

#include

#define  MaxSize 100       //最多结点数

typedef  struct  QNode

{    

    float  weight;

    float  value;

    int    ceng;

    struct  QNode *parent;

    bool leftChild;

}QNode,*qnode;             //存放每个结点

typedef struct 

    qnode  Q[MaxSize]; 

    int front,rear;

}SqQueue;          //存放结点的队列

SqQueue  sq;

float bestv=0; //最优解

int n=0;                      //实际物品数

float w[MaxSize];           //物品的重量

float v[MaxSize];            //物品的价值

int bestx[MaxSize];          // 存放最优解

qnode bestE;

void InitQueue(SqQueue &sq ) //队列初始化

{

    sq.front=1;

    sq.rear=1;

}

bool QueueEmpty(SqQueue sq) //队列是否为空

{

    if(sq.front==sq.rear)

        return true;

    else 

        return false;

}

void EnQueue(SqQueue &sq,qnode b)//入队

{

    if(sq.front==(sq.rear+1)%MaxSize)

    {

        printf("队列已满!");

        return ;

    }

    sq.Q[sq.rear]=b;

    sq.rear=(sq.rear+1)%MaxSize;

}

qnode DeQueue(SqQueue &sq)//出队

{

    qnode e;

    if(sq.front==sq.rear)

    {

        printf("队列已空!");

        return 0;

    }

    e=sq.Q[sq.front];

    sq.front=(sq.front+1)%MaxSize;

    return e;

}

void  EnQueue1(float wt,float vt, int i ,QNode *parent, bool leftchild)

{

    qnode b;

    if (i==n)      //可行叶子结点

    {

        if (vt==bestv)

        {

            bestE=parent;

            bestx[n]=(leftchild)?1:0;

        }

        return;

    }

    b=(qnode)malloc(sizeof(QNode));   //非叶子结点

b->weight=wt;

b->value=vt;

b->ceng=i;

b->parent=parent;

b->leftChild=leftchild;

    EnQueue(sq,b);

void  maxLoading(float w[],float v[],int c)

    float wt=0;

    float vt=0;

    int i=1;      //当前的扩展结点所在的层

    float ew=0;      //扩展节点所相应的当前载重量

    float ev=0;       //扩展结点所相应的价值

    qnode e=NULL;

    qnode t=NULL;

    InitQueue(sq);

    EnQueue(sq,t);       //空标志进队列

    while (!QueueEmpty(sq))

    {  

        wt=ew+w[i]; 

        vt=ev+v[i];

     if (wt <= c)

        {

         if(vt>bestv)

                bestv=vt;

            EnQueue1(wt,vt,i,e,true);   // 左儿子结点进队列

        }   

        EnQueue1(ew,ev,i,e,false);        //右儿子总是可行;

        e=DeQueue(sq);         // 取下一扩展结点

        if (e == NULL)

        {

            if (QueueEmpty(sq))   break;

            EnQueue(sq,NULL);        // 同层结点尾部标志

            e=DeQueue(sq);      // 取下一扩展结点

            i++;

        }

     ew=e->weight; //更新当前扩展结点的值

     ev=e->value;

    }

    printf("最优取法为:\\n");

for( int j=n-1;j>0;j--) //构造最优解

    {

     bestx[j]=(bestE->leftChild?1:0);

     bestE=bestE->parent;

    }

for(int k=1;k<=n;k++)

    {

        if(bestx[k]==1)

            printf("\\n物品%d:重量:%.1f,价值:%.1f\\n",k,w[k],v[k]);

    }

    printf("\\n");

    printf("最优价值为:%.1f\\n\\n",bestv);

      

}

void main()

{

    int c;

    float ewv[MaxSize];

printf("510专区\\n");

printf("请输入物品的数量:\\n");

    scanf("%d",&n);

    printf("请输入背包容量:\\n");

    scanf("%d",&c);

    printf("\\n请输入物品价值和重量:\\n\\n");

for(int i=1;i<=n;i++)

    {

        printf("物品%d:",i);

        scanf("%f%f",&ewv[i],&w[i]);

        v[i]=w[i]*ewv[i];

        printf("\\n");

    }

}

实验结果:    

    maxLoading(w, v, c);下载本文

显示全文
专题