1. 程式人生 > 其它 >[實驗]貪心演算法之揹包問題 基於C++實現

[實驗]貪心演算法之揹包問題 基於C++實現

技術標籤:演算法演算法貪心演算法c++

一、 實驗內容:

揹包問題:
給定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,各物品價值和重量如下:

價值重量
204
4040
306
205
102

則將
重: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;
}