簡單的背包問題

來源:互聯網
上載者:User

 背包問題(Knapsack problem)是一種組合最佳化的NP完全問題。問題可以描述為:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內,我們如何選擇,才能使得物品的總價格最高。問題的名稱來源於如何選擇最合適的物品放置於給定背包中。——引用自百度百科

背包問題是熟知的不可計算問題,這裡唯寫一下簡單的“0/1背包問題”和“連續背包問題”,至於有興趣的讀者可以再去深入瞭解一下“完全背包問題”和“多重背包問題”

0/1背包問題:

題目:有N件物品和一個容量為V的背包。第i件物品的重量是c[i],價值是w[i]。求解將哪些物品裝入背包可使這些物品的重量總和不超過背包容量,且價值總和最大。

這是最基礎的背包問題,特點是:每種物品僅有一件,可以選擇放或不放。如果每次可以拿走某一物品的任意一部分,則這一問題稱為連續背包問題

通常0/1背包問題可以採用遵歸演算法來解,連續背包問題可以採用貪心演算法來求解

遞迴演算法求解0/1背包問題的範例程式碼:

 

#include<stdio.h>#include<stdlib.h>//該函數首先嘗試將最後一件物品放入背包,則物品減少一件,背包可用體積相應減少,然後對目前狀態進行遞迴……//若有解則遞迴結束;若無解則拋棄最後一件物品,然後對目前狀態進行遞迴……int knap(int s, int n, int w[]) {    if ( s == 0 )        return (1);    else if ( s<0 || s>0 && n<1 )        return(0);    else if ( knap(s - w[n-1], n - 1, w)==1 ) { //從後往前裝,如果裝滿第n個包,剩餘的重量仍然可以在剩餘的n-1包中放下,那麼就將第n個封裝滿。        printf("result: n=%d ,w[%d]=%d  \n", n, n-1, w[n-1]);        return (1);    }    else        return ( knap(s, n - 1, w) );//如果裝滿第n個包後,剩餘的重量不能在剩餘的n-1包中放下,那麼就不用第n個包,考慮能不能用第n-1個包。}//s:背包的重量 n:物品的數量 w[]:每件物品的重量int main() {    int* w;    int s = 0, n = 0, result = 0, i = 0;    printf("please  input s = ");/*輸入s*/    scanf("%d", &s);    printf("please  input n = ");/*輸入n*/    scanf("%d", &n);    w = (int*)malloc(n*sizeof(int));    printf("please input the %d numbers(weight):\n", n);/*輸入重量*/    for (i = 0; i < n; i++)        scanf("%d", w+i);    result = knap(s, n, w);    if (result == 0)        printf("no solution!\n");    return 0;}

 

參考資料:

1.http://zhidao.baidu.com/question/142355040.html

2.http://zhidao.baidu.com/question/189247470.html?fr=qrl&cid=866&index=1&fr2=query

3.http://www.cnblogs.com/jillzhang/archive/2007/10/06/915035.html

4.http://88myway.blog.163.com/blog/static/6926644720097124916791/

5.http://www.cppblog.com/baby-fly/archive/2009/10/24/99356.html     //非遞迴演算法

6.http://zhidao.baidu.com/question/54929204.html?fr=qrl&cid=93&index=5&fr2=query     //採用鏈表方法

7.http://zhidao.baidu.com/question/29685294.html?fr=qrl&cid=93&index=1&fr2=query    //採用棧的方法

貪心演算法求解連續背包問題的範例程式碼:

 

//連續背包問題#include <iostream>#include <algorithm> #include <vector>using namespace std;#define Max 10 //初始化背包重量為10typedef struct{float price;float weight;float rate;//價格與重量的比float num;//每件物品是否能完整放下}element;bool bigger(element a,element b){return a.rate>b.rate;}void knapsack(vector<element> &test,float m){int i;for(i=0;i!=test.size();i++){if(test[i].weight>m)break;test[i].num=1;//第i件物品可以完全放到背包中m=m-test[i].weight;}if(m>0){test[i].num=m/test[i].weight;//第i件物品只能放部分i++;while(i!=test.size()){//當不是最後一件物品不能放進時test[i].num=0;i++;}}}void main(){int i,n;float m=Max;vector<element> data;element da;cout<<"input the num of goods:";cin>>n;for(i=0;i<n;i++){cout<<"input the "<<i<<" price:";cin>>da.price;cout<<"input the "<<i<<" weight:";cin>>da.weight;;da.rate=da.price/da.weight;data.push_back(da);}cout<<"build dataset:"<<endl;for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].weight<<" "<<data[i].rate<<endl;sort(data.begin(),data.end(),bigger);//將性價比最高的排在前面cout<<"after sort;"<<endl;for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].weight<<" "<<data[i].rate<<endl;cout<<"result:"<<endl;knapsack(data,m);for(i=0;i!=data.size();i++)cout<<data[i].price<<" "<<data[i].num<<endl;}

 

參考資料:

1.http://apps.hi.baidu.com/share/detail/16423759
2.http://wenku.baidu.com/view/ce3ebbc69ec3d5bbfd0a743e.html
3.http://wenku.baidu.com/view/afcc3e116edb6f1afe001f04.html?from=related&hasrec=1
4.http://www.cnblogs.com/gentleming/archive/2010/07/17/1779515.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.