实验报告 分支限界法01背包

《算法设计与分析》实验报告六
学号: 1004091130           
姓名:  金玉琦               
日期:  2011-11-17             
得分:               
    一、实验内容:
运用分支限界法解决0-1背包问题
    二、所用算法的基本思想及复杂度分析:
分支限界法
分支限界法按广度优先策略遍历问题的解空间树, 在遍历过程中, 对已经处理的每一个结点根据限界函数估算目标函数的可能取值, 从中选取使目标函数取得极值                    的结点优先进行广度优先搜索, 从而不断调整搜索方向, 尽快到问题的解。因为限界函数常常是基于问题的目标函数而确定的, 所以, 分支限界法适用于求解最优化问题。
0-1背包问题
      1)基本思想
给定n 物品和一个容量为C 的背包, 物品i 的重量是Wi, 其价值为Vi , 0/ 1 背包问题是如何选择装入背包的物品(物品不可分割) , 使得装入背包中物品的总价值最大,一般情况下, 解空间树中第i 层的每个结点, 都代表了对物品1~ i 做出的某种特定选择, 这个特定选择由从根结点到该结点的路径唯一确定: 左分支表示装入物品, 右分支表示不装入物品。对于第i 层的某个结点, 假设背包中已装入物品的重量是w, 获得的价值是v, 计算该结点的目标函数上界的一个简单方法是把已经装入背包中的物品取得的价值v, 加上背包剩余容量W - w 与剩下物品的最大单位重量价值vi + 1/ wi + 1的积,于是,得到限界函数:
u b = v + ( W - w) × ( vi + 1/ wi + 1 )
    根据限界函数确定目标函数的界[ down , up],然后, 按照广度优先策略遍历问题的空    间树。
2)复杂度分析
时间复杂度是O(2n);
三、源程序及注释:
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<iomanip>
using namespace std;
int *x;
struct node
    {
              //结点表结点数据结构
      node  *parent,//父结点指针
            *next; //后继结点指针
      int    level,//结点的层
              bag,//节点的解
              cw,//当前背包装载量
              cp;//当前背包价值           
      float  ub; //结点的上界值
    };
class Knap
    {ebsco
        private:
        struct    node      *front, //队列队首
                  *bestp,*first; //解结点、根结点
        int      *p,*w,n,c,*M;//背包价值、重量、物品数、背包容量、记录大小顺序关系
        long      lbestp;//背包容量最优解
        public:
        void Sort();
        Knap(int *pp,int *ww,int cc,int nn);
        ~Knap();
        float Bound(int i,int cw,int cp);//计算上界限
        node *nnoder(node *pa,int ba,float uub);//生成一个结点 ba=1生成左节点 ba=0生成右节点
        void addnode(node *nod);//将结点添加到队列中
        void deletenode(node *nod);//将结点队列中删除
        struct node *nextnode(); //取下一个
        void display(); //输出结果
        void solvebag(); //背包问题求解
    };
Knap::Knap(int *pp,int *ww,int cc,int nn)
    {
        int i;
        n=nn;
        c=cc;
        p=new int[n];
        w=new int[n];
        M=new int[n];
        for(i=0;i<n;i++)
        {
            p[i]=pp[i];
            w[i]=ww[i];
            M[i]=i;
        }
        front=new node[1];
        front->next=NULL;
        lbestp=0;
        bestp=new node[1];
        bestp=NULL;
        Sort();
    }
Knap::~Knap()
    {
        delete []first;
        delete []front;
        delete []bestp;
        delete []p;
        delete []w;
    }
float Knap::Bound(int i,int cw,int cp)
    {// 计算上界
        int cleft=c-cw;
        float b=(float)cp;
        while (i<n&&w[i]<=cleft)
        {
            cleft-=w[i];
            b+=p[i];
            i++;
        }
        if (i<n) b+=1.0*p[i]/w[i]*cleft;
        return b;
    }
node * Knap::nnoder(struct node *pa,int ba,float uub)
    {//生成一个新结点
        node * nodell=new(node);
        nodell->parent=pa;
        nodell->next=NULL;
        nodell->level=(pa->level)+1;
        nodell->bag=ba;
        nodell->ub=uub;
        if(ba==1)
        {
            nodell->cw=pa->cw+w[pa->level];
            nodell->cp=pa->cp+p[pa->level] ;
        }
        else
        {
            nodell->cw=pa->cw;
            nodell->cp=pa->cp;
        }
        return(nodell);
        }
void Knap::addnode(node *no)
    {//将结点加入优先队列
        node *p=front->next,*next1=front;
        float ub=no->ub;
        while(p!=NULL)
        {
            if(p->ub<ub)
                {no->next=p;next1->next=no;break;}
            next1=p;
            p=p->next;
        }
        if(p==NULL){next1->next=no;
        }
    }
node *Knap::nextnode()
    {//取上限最大结点
        node *p=front->next;
        front->next=p->next;
        return(p);
    }
void Knap::Sort()
    {
        int i,j,k,kkl;
        float minl;
        for(i=1;i<n;i++)
        { 
            minl=1.0*p[i]/w[i];
            k=0;
            for(j=1;j<=n-i;j++)
                {
条子生                  if(minl<1.0*p[j]/w[j])
                    {
                        minl=1.0*p[j]/w[j];
姚海星                        swap(p[k],p[j]);鱼塘理论
                        swap(w[k],w[j]);
                        swap(M[k],M[j]);         
                        k=j;
                    }
                }
        }
    }
void Knap::display()
    {
        int i;
        cout<<"最大价值是:"<<lbestp<<endl;
        for(i=n;i>=1;i--)
浙江省人口与计划生育条例
            { 
                x[M[i-1]]=bestp->bag;
                bestp=bestp->parent;
            }
        cout<<"变量值为:"<<endl;
        for(i=1;i<=n;i++)
        cout<<"x("<<setw(2)<<i<<")="<<x[i-1]<<endl;
    }
void Knap::solvebag()
    {//背包问题求解
        int i;
        float ubb;
        node *aa;
        first=new node[1]; //根结点
        first->parent=NULL;
        first->next=NULL;
        first->level=0;
>托姆布雷

本文发布于:2024-09-21 13:42:29,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/332315.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:结点   背包   物品   函数   问题
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议