[實驗]貪心演算法之揹包問題 基於C++實現
阿新 • • 發佈:2020-12-10
一、 實驗內容:
揹包問題:
給定n種物品,1個揹包,揹包容量為c,每個物品i的價值為vi,重量為wi,如何選擇裝入物品能使揹包的總價值最大?
形式化描述:給定c >0, wi >0, vi >0 , 1≤i≤n.要求找一n元向量
A=(x1,x2,…,xn), 0<=xi<=1
【0~1表示取物品的某一部分】,1<=i<=n,使得
∑ wixi≤c
【物品的重量和小於揹包總容量】而且∑ vixi達到最大。
演算法思路:將物品按照單位重量價值進行排序(從大到小),將盡可能多的單位重量價值最高的物品裝入揹包,若將這種物品全部裝入揹包後,揹包還有多餘容量,則選擇單位重量價值次高的並儘可能多地裝入揹包。如果最後一件物品無法全部裝入,則計算可以裝入的比例,然後按比例裝入。
二、 實驗結果
三、實驗分析與結論
現有5個物品,1個揹包,揹包容量為45,各物品價值和重量如下:
價值 | 重量 |
---|---|
20 | 4 |
40 | 40 |
30 | 6 |
20 | 5 |
10 | 2 |
則將
重:4、價值:20的物品、重:6、價值:30的物品、重:2、價值:10的物品、重:5、價值:20的物品全放入揹包
而重:40、價值:40的物品的0.7被放入了揹包
四、原始碼:
#include "stdafx.h" #include <iostream> #include <algorithm> using namespace std; struct item{ int weight;//物品的重量 int value;//物品的價值 float bi;//物品單位重量的價值 float rate;//使用率:1代表物品完整放入,小於1代表被分割後放入 }items[100]; bool cmp(const item &a,const item &b){ return a.bi>b.bi; } int main(){ int n;//n件物品 float c;//揹包容量為c cout<<"輸入物品件數和揹包容量:"<<endl; cin>>n>>c; cout<<"依次輸入每件物品的價值和重量:"<<endl; //v[n]:n件物品的價值,w[n]:n件商品的重量 float *v = new float[n]; float *w = new float[n]; for(int i=0;i<n;i++){ cin>>items[i].value>>items[i].weight; items[i].bi=items[i].value/items[i].weight;//計算單位重量價值 items[i].rate=0;//初始化每件物品的使用率 } sort(items,items+n,cmp);//按照單位重量的價值排序 int sum=0,j=0; for(j=0;j<n;j++){ if(items[j].weight<=c){//選擇單位價值重量最大的並且不超過揹包容量的 items[j].rate=1; sum+=items[j].weight; c-=items[j].weight; cout<<"重:"<<items[j].weight<<"、價值:"<<items[j].value<<"的物品被放入了揹包"<<endl<<"放入比例:"<<items[j].rate<<endl; } else break; } if(j<n){//物品未裝完 items[j].rate=c/items[j].weight;//揹包容量還剩c,計算出未裝入的物品能裝多少的比例 sum+=items[j].rate*items[j].weight;//加上裝入部分比例物品的重量 cout<<"重:"<<items[j].weight<<"、價值:"<<items[j].value<<"被放入了揹包"<<endl<<"放入比例:"<<items[j].rate<<endl; } delete[] v , w; return 0; }