贪心法——部分背包问题

原创 2016年05月31日 21:16:30

贪心法——部分背包问题

部分背包问题。有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。每一个物体都可以只取走一部分,价值和重量按比例计算。

和最优转载问题一样,这题也可以用贪心法解决。但是这题有两个因素,重量和价值,所以应该综合考虑两个因素。

直观的贪心策略是:优先拿性价比高的,也就是viwi大的,直到重量恰好为C

由于可以拿部分,因此一定能保证重量恰好为C(除非n个物体总重量不足C),并且除了拿的最后一个物体可能是拿部分以外,其他拿的都是拿整个。

部分背包问题算法实现

// 物体类型
struct Matter {
    // 重量
    float w;
    // 价值
    float v;
    // 从大到小排序
    bool operator < (const Matter &m) const {
        return (v / w) > (m.v / m.w);
    }
};

// 贪心法
// 部分背包问题
void optionalLoad(Matter *m, int n, float C) {
    sort(m, m + n);
    float retain = C;
    float sumValue = 0;
    int i;
    for(i = 0; i < n; i++) {
        if(m[i].w <= retain) {
            cout << "第" << i + 1 << "个放入背包的重量为:" << m[i].w << "\t价值为:" << m[i].v << endl;
            retain -= m[i].w;
            sumValue += m[i].v;
        } else {
            if(retain != 0) {
                // 最后一个能放入重量的价值
                float retainValue = m[i].v / m[i].w * retain;
                cout << "第" << i + 1 << "个放入背包的重量为:" << retain << "\t价值为:" << retainValue << endl;
                sumValue += retainValue;
            }
            break;
        }
    }
    cout << "总价值为:" << sumValue << endl << endl;
}

测试主程序

#include <iostream>
#include <algorithm>

using namespace std;

// 物体类型
struct Matter {
    // 重量
    float w;
    // 价值
    float v;
    // 从大到小排序
    bool operator < (const Matter &m) const {
        return (v / w) > (m.v / m.w);
    }
};

// 贪心法
// 部分背包问题
void optionalLoad(Matter *m, int n, float C) {
    sort(m, m + n);
    float retain = C;
    float sumValue = 0;
    int i;
    for(i = 0; i < n; i++) {
        if(m[i].w <= retain) {
            cout << "第" << i + 1 << "个放入背包的重量为:" << m[i].w << "\t价值为:" << m[i].v << endl;
            retain -= m[i].w;
            sumValue += m[i].v;
        } else {
            if(retain != 0) {
                // 最后一个能放入重量的价值
                float retainValue = m[i].v / m[i].w * retain;
                cout << "第" << i + 1 << "个放入背包的重量为:" << retain << "\t价值为:" << retainValue << endl;
                sumValue += retainValue;
            }
            break;
        }
    }
    cout << "总价值为:" << sumValue << endl << endl;
}

int main() {
    while(true) {
        // n个物体
        int n;
        cout << "请输入物体总数(0退出):";
        cin >> n;
        if(!n) {
            break;
        }
        float C;
        cout << "请输入不超过的总重量:";
        cin >> C;
        Matter m[n];
        for(int i = 0; i < n; i++) {
            cout << "第" << i + 1 << "个物体的重量、价值分别为:";
            cin >> m[i].w;
            cin >> m[i].v;
        }
        //
        cout << "总价值最高的组合和价值为:" << endl;
        optionalLoad(m, n, C);
    }
    return 0;
}

输出数据

请输入物体总数(0退出):5
请输入不超过的总重量:101个物体的重量、价值分别为:3 92个物体的重量、价值分别为:9 33个物体的重量、价值分别为:2 44个物体的重量、价值分别为:4 25个物体的重量、价值分别为:1 1
总价值最高的组合和价值为:
第1个放入背包的重量为:3        价值为:92个放入背包的重量为:2        价值为:43个放入背包的重量为:1        价值为:14个放入背包的重量为:4        价值为:2
总价值为:16

请输入物体总数(0退出):5
请输入不超过的总重量:101个物体的重量、价值分别为:2 32个物体的重量、价值分别为:3 23个物体的重量、价值分别为:6 14个物体的重量、价值分别为:4 45个物体的重量、价值分别为:5 1
总价值最高的组合和价值为:
第1个放入背包的重量为:2        价值为:32个放入背包的重量为:4        价值为:43个放入背包的重量为:3        价值为:24个放入背包的重量为:1        价值为:0.2
总价值为:9.2

请输入物体总数(0退出):3
请输入不超过的总重量:9.21个物体的重量、价值分别为:1 12个物体的重量、价值分别为:2 23个物体的重量、价值分别为:3 3
总价值最高的组合和价值为:
第1个放入背包的重量为:1        价值为:12个放入背包的重量为:2        价值为:23个放入背包的重量为:3        价值为:3
总价值为:6

请输入物体总数(0退出):0

Process returned 0 (0x0)   execution time : 921.488 s
Press any key to continue.
版权声明:如需转载,请联系本人获取许可且必须注明出处,详见联系方式。

部分背包问题(贪心算法)

部分背包问题 题目描述 给定一个最大容量为m的背包和n种问题,有食盐、白糖、大米等。已知第i种食品最多有wi公斤,其价值为vi元/公斤,编程确定一个装货方案,使得装入背包中的所有食品的总价值最大。 输...
  • C_Khalid
  • C_Khalid
  • 2016年08月27日 16:13
  • 2652

《算法导论》之动态规划和贪心算法 0-1背包问题

1、前言   前段时间忙着搞毕业论文,看书效率不高,导致博客一个多月没有更新了。前段时间真是有些堕落啊,混日子的感觉,很少不爽。今天开始继续看算法导论。今天继续学习动态规划和贪心算法。首先简单的...
  • sgs1018
  • sgs1018
  • 2013年10月27日 18:34
  • 1205

贪心算法(二)——一般背包问题

题目 有一个背包,最多放M kg的物体(物体大小不限); 有n个物体,每个物体的重量为Wi,每个物体完全放入背包后可获得收益Pi。问:如何放置能获得最大的收益? 注:背包问题分为两种,若每个...
  • u010425776
  • u010425776
  • 2017年04月05日 21:19
  • 1954

贪心法部分背包问题的实现

1. 给定n个物品,物品价值分别为P1,P2,…,Pn,物品重量分别为W1,W2,…,Wn,背包容量为M。每种物品可部分装入到背包中。输出X1,X2,…,Xn, 0...
  • Jason__ccc
  • Jason__ccc
  • 2016年11月29日 22:10
  • 502

ACM知识点 之 贪心(4)部分背包问题

转载地址:http://blog.csdn.net/liuxucoder 部分背包问题虽说是归于背包问题的一种,而且背包问题大多数是通过动态规划的出的结果,但是贪心算法解部分背包,不管是思想还...
  • xia842655187
  • xia842655187
  • 2016年07月18日 19:39
  • 1004

部分背包问题-贪心法源码

#include #include //#include using namespace std; float Value[100]={0}; float Weight[100]={0}; stru...
  • LC_1994
  • LC_1994
  • 2015年10月30日 18:57
  • 456

贪心法:部分背包问题

  • yahreso
  • yahreso
  • 2009年09月05日 00:23
  • 329

Java描述贪心算法解决背包问题

思路: 首先将物品根据性价比排好序在一个集合里,性价比=价格/重量... 然后根据性价比从大到小依次依次放入背包,如果没办法放入这个物品的全部,就放入一部分,如果可以放入全量物品,就放入全量物品。 ...
  • u013803262
  • u013803262
  • 2016年02月16日 13:17
  • 2250

用贪心算法解背包问题Java实现

用贪心算法解背包问题,给出的物体是无序的,需要我们按照物体的单位重量的价值进行排序....
  • shuoyuechenxing
  • shuoyuechenxing
  • 2017年04月23日 15:20
  • 696

背包问题-贪心法-java实现

完全背包问题 一个旅行者有一个最多能用m公斤的背包,现在有n种物品,每件的重量分别是W1,W2,...,Wn, 每件的价值分别为C1,C2,...,Cn.若的每种物品的件数足够多. 求旅行者能获得的最...
  • a137268431
  • a137268431
  • 2015年09月07日 16:47
  • 1615
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:贪心法——部分背包问题
举报原因:
原因补充:

(最多只允许输入30个字)