Love coding,enjoy life。
阿新 • • 發佈:2019-01-07
問題描述
假設有一個能裝入總體積為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; }
原始碼下載: