简单的背包问题

来源:互联网 发布:python 增量拷贝文件 编辑:程序博客网 时间:2024/06/11 21:14

 背包问题(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