C++背包问题的LC分枝-限界算法LCKNAP

余祥宣, 崔国华, 邹海明. 计算机算法基础.3版[M]. 华中科技大学出版社, 2006.
P233-234 算法9.8
程序的输入是一个名字为input.txt的文件,保存时注意编码格式再VS上运行的话要保存为ANSI编码,如果需要的话我可以上传一份

6 4
10 10 12 18
2 4 6 9

#include<iostream>
#include<fstream>
using namespace std;

#define MAX 15
#define _e 0.0001

struct NODE { //结点数据结构 
    NODE *PARENT=NULL; //指向父结点指针 
    NODE *next=NULL; //后继结点指针 
    int LEVEL=-1; //结点的所在的层数 
    int TAG=-1; //左右孩子的标志,1为左孩子,0为右孩子 
    int CU=-1; //目前背包剩余空间 
    int PE=-1; //目前已装入物品有效益值 
    int LB=-1; //结点的下界值 
    float UB=-1; //结点的上界值 
};

int P[MAX];
int W[MAX];

int N;//物品数量
int M;//背包最大空间

NODE *head; //活动结点队列队头 
NODE *ANS;

void INIT() //初始化队列 
{
    head = new(NODE);
    head->next = NULL;
    ANS = new(NODE);
}
void ADD(NODE *node)
{
    node->next = head->next;
    head->next = node;
}
NODE* GETNODE()
{
    return new(NODE);
}
void NEWNODE(NODE *par, int lev, int t, int cap, int prof, int lb,int ub)
{
    NODE *I=GETNODE();
    I->PARENT = par;
    I->LEVEL = lev;
    I->TAG = t;
    I->CU = cap;
    I->PE = prof;
    I->LB = lb;
    I->UB = ub;
    ADD(I);
}

NODE* NEXLIVENODE() //下一扩展结点(取下限LBB最大结点) 
{
    NODE *p = head->next, *choice = p;
    int LBB = p->LB;
    while (p)
    {
        if (p->LB > LBB)
            choice = p;
        p = p->next;
    }
    return(choice);
}
void DEQUEUE(NODE* node) //将结点i从优先队列中删除 
{
    NODE *pre = head, *p = head->next;
    while (p != node)
    {
        pre = p;
        p = p->next;
    }
    pre->next = p->next;
}
NODE* LARGEST(NODE *node)
{
    node = NEXLIVENODE(); //下一扩展结点 
    DEQUEUE(node); //将结点从队列中删除 
    return node;
}
void FINISH(int L, NODE *ANS, int N)
{
    cout << "VALUE OF OPTIMAL FILLING IS\n";
  cout<<L;
    cout << "\nOBJECT IN KNAPSACK ARE\n";
    for (int j = N; j >= 1; j--)
    {
        if (ANS->TAG == 1)
            cout << 'x' << j << ' ';
        ANS = ANS->PARENT;
    }
    cout << endl;
}
void LUBOUND(int P[], int W[], int rw, int cp, int N, int k, int &LBB, float &UBB)
{
    int c;
    LBB = cp;
    c = rw;
    for (int i = k; i <= N; i++)
    {
        if (c < W[i])
        {
            UBB = (float)(LBB + c * P[i] / W[i]);
            for (int j = i + 1; j <= N; j++)
            {
                if (c >= W[j])
                {
                    c = c - W[j];
                    LBB = LBB + P[j];
                }
            }
            return;
        }
        c = c - W[i];
        LBB = LBB + P[i];
    }
    UBB = (float)LBB;
}
void LCKNAP(int P[], int W[], int M,int N,float e)
{
    int L, LBB=0, cap, prof;
    float UBB = 0;
    int  X;
    INIT();
    NODE *E=GETNODE();
    E->PARENT = 0;
    E->LEVEL = 1;
    E->CU = M;
    E->PE = 0;
    E->TAG = 0;
    LUBOUND(P, W, M, 0, N, 1, LBB, UBB);
    L = LBB - e; 
    E->UB = UBB;
    E->LB = LBB;
    int i;
    while (E->UB>L)
    {
        i = E->LEVEL;
        cap = E->CU;
        prof = E->PE;
        if (i == N + 1)
        {
            if (prof > L)
            {
                L = prof;
                ANS = E;
            }           
        }
        else
        {
            if (cap >= W[i])
                NEWNODE(E, i + 1, 1, cap - W[i], prof + P[i], E->LB,E->UB);
            LUBOUND(P, W, cap, prof, N, i + 1, LBB, UBB);
            if (UBB > L)
            {
                NEWNODE(E, i + 1, 0, cap, prof, LBB, UBB);
                if (LBB - e > L)
                    L = LBB - e;
            }
        }
        if (head->next == NULL) 
            break;
        E=LARGEST(E);
    }
    FINISH(L, ANS, N);
}

int main()
{

    ifstream in("input.txt");
    in >> M >> N;
    P[0] = W[0] = 0;
    for (int i = 1; i <=N; i++)
        in >> P[i];
    for (int i = 1; i <= N; i++)
        in >> W[i];
    cout << "各个物品的价值和重量为:" << endl;
    cout << "Name\tP\tW" << endl;
    for (int i = 1; i <= N; i++)
        cout << "x" << i << "\t" << P[i] << "\t" <<W[i] << endl;
    cout << "M=" << M << "\tN=" << N<<endl;
    LCKNAP(P, W, M, N,_e);
    cout << endl;
    system("pause");
    return 0;
}

运行结果
《C++背包问题的LC分枝-限界算法LCKNAP》
《C++背包问题的LC分枝-限界算法LCKNAP》

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/ujsDui/article/details/79003972
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞