1. 程式人生 > >Love coding,enjoy life。

Love coding,enjoy life。

問題描述

假設有一個能裝入總體積為T的揹包和n件體積分別為w1,w2,wn的物品,能否從n件物品中挑選若干件恰好裝滿揹包,即使w1+w2++wm=T,要求找出所有滿足上述條件的解。

例如:當T=10,各件物品的體積{1,8,4,3,5,2}時,可找到下列4組解:

  (1,4,3,2)

  (1,4,5)

  (8,2)

  (3,5,2)

實現提示

可利用回溯法的設計思想來解決揹包問題。首先,將物品排成一列,然後,順序選取物品裝入揹包,若已選取第i件物品後未滿,則繼續選取第i+1件,若該件物品太大不能裝入,則棄之,繼續選取下一件,直至揹包裝滿為止。

如果在剩餘的物品中找不到合適的物品以填滿揹包,則說明

剛剛裝入的物品不合適,應將它取出棄之一邊,繼續再從它之後的物品中選取,如此重複,直到求得滿足條件的解,或者無解。

由於回溯求解的規則是後進先出,自然要用到

進一步考慮:如果每件物品都有體積和價值,揹包又有大小限制,求解揹包中存放物品總價值最大的問題解---最優解或近似最優解。

stackbag.h

#ifndef _STACKBAG_H
#define _STACKBAG_H
#include<iostream>
#include<map>
class stone{
public:
    int volume;
    int value;
    stone(){};
    void setparams(int vo,int va){volume=vo;value=va;};
};
class mystack{
private:
std::map<int,int> valuesmap;
enum{max=20};
stone items[max];
int numofsolution;
int t;
int top;
public:
mystack(int T):top(0){t=T;numofsolution=0;};
bool isempty() const{return top==0;};
bool isfull() const{return top==max;};
bool pop(stone&);
bool push(stone);
void solution(stone* a,int n);
int sum();
void clearstack() {top=0;};
void print();
void bestsolution();
};
int mystack::sum()
{
    int s=0,n=top;
    while(n--) s+=items[n].volume;
    return s;
}
bool mystack::pop(stone& it)
{
    if(!isempty())
    {
        it=items[--top];
        return true;
    }
    std::cout<<"stack is full\n";
    return false;
}
bool mystack::push(stone it)
{
    if(!isfull())
    {
        items[top++]=it;
        return true;
    }
    return false;
}

void mystack::print()
{
    int allvalue=0;
    std::cout<<"get an answer:";
    for(int i=0;i<top;i++)
    {
        std::cout<<items[i].volume<<" ";
        allvalue+=items[i].value;
    }
    std::cout<<std::endl<<"sum of the value is:"<<allvalue<<std::endl;
    numofsolution++;
    valuesmap.insert(std::pair<int,int>(numofsolution,allvalue));
}
void mystack::solution(stone* b,int n)
{
    stone it;
    int j;
    for(int i=0;i<n;i++)
    {
        push(b[i]);
        j=i+1;
        while(top<n+1&&top>0)
        {
            if(j<n)
            {
                if(sum()+b[j].volume<t) push(b[j]);
            else if(sum()+b[j].volume==t)
            {
                push(b[j]);
                print();
                pop(it);
            }
            j++;
            }
            else
            {
                pop(it);
                for(j=i+1;j<n;j++)
                {
                    if(b[j].value!=it.value||b[j].volume!=it.volume)
                    {
                        j++;
                    }
                    else break;
                }
                j++;
            }
        }
        clearstack();
    }
}
void mystack::bestsolution()
{
    std::cout<<"the best solution is number "<<valuesmap.begin()->first<<"\nthe max value is:"<<valuesmap.begin()->second;
}
#endif // _STACKBAG_H

main.cpp
#include<iostream>
#include"stackbag.h"
int main()
{
    int stonenumber,bagsize;
    std::cout<<"input number of the stones:";
    std::cin>>stonenumber;
    std::cout<<"input the size of the bag:";
    std::cin>>bagsize;
    std::cout<<"input the volume and the value of the stone one by one\n";
    stone* stones=new stone[stonenumber];
    int vo,va;
    for(int i=0;i<stonenumber;i++)
    {
        std::cin>>vo>>va;
        stones[i].setparams(vo,va);
    }
    mystack sta=mystack(bagsize);
    sta.solution(stones,stonenumber);
    sta.bestsolution();
    delete stones;
    return 0;
}


原始碼下載: