算法日记(十二)之贪心算法

在前面我们已经有分享过递归和回溯算法的思想,再结合最近在学图的应用时,遇到最小生成树和最短路径等问题时,都提到一个贪心的思想。今天,我们就来总的看一下这个贪心算法的内容吧

1.贪心算法(有时也叫贪婪算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法。贪心算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果

2.贪心算法一般按如下步骤进行:

①建立数学模型来描述问题 。

②把求解的问题分成若干个子问题 。

③对每个子问题求解,得到子问题的局部最优解 。

④把子问题的解局部最优解合成原来解问题的一个解 。

3.贪心算法是一种对某些求最优解问题的更简单、更迅速的设计技术。贪心算法的特点是一步一步地进行,常以当前情况为基础根据某个优化测度作最优选择,而不考虑各种可能的整体情况,省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪心算法采用自顶向下,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题,通过每一步贪心选择,可得到问题的一个最优解。虽然每一步上都要保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯 。

4.贪心算法也存在如下问题:

①不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑 ;

②贪心算法一般用来解决求最大或最小解 ;

③贪心算法只能确定某些问题的可行性范围 。

5.下面我们就来说一个经典问题——背包问题来体会一下贪心算法吧

题目:有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

在这里插入图片描述

 用贪心算法解背包问题的基本步骤:首先计算每种物品单位重量的价值v[i]/w[i],然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直地进行下去,直到背包装满为止。

代码实现:

#include
using namespace std;
//按照单位重量的价值量大小降序排列
void Sort(int n, float* w, float* v)//最后得到从大到小的单位重量价格量
{
    int i, j;
    float temp1, temp2;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n - i; j++)//冒泡排序
        {
            temp1 = v[j] / w[j];
            temp2 = v[j + 1] / w[j + 1];
            if (temp1 < temp2)
            {
                swap(w[j], w[j + 1]);
                swap(v[j], v[j + 1]);
            }
        }
}
int main()
{
    float w[101];//用来表示每个物品的重量
    float v[101];//用来表示每个物品的价值量
    float x[101];//表示最后放入背包的比例
    int n;//物品数
    float M;//背包最大容纳重量
    cout << "请输入物品数" << endl;
    cin >> n;
    cout << "请输入背包最大容量" << endl;
    cin >> M;
    //依次输入每件物品的重量和价值量
    cout << "依次输入每件物品的重量和价格量" << endl;
    for (int i = 1; i <= n; i++)
        cin >> w[i] >> v[i];
    //按照单位重量的价值量大小降序排列
    Sort(n, w, v);
    int i;
    for (i = 1; i <= n; i++)
        x[i] = 0;//初始值,未装入背包,x[i]=0
    float c = M;//更新背包容纳量
    for (i = 1; i <= n; i++)
    {
        if (c < w[i])  break;//不能完全装下
        x[i] = 1;
        c = c - w[i];
    }
    if (i <= n)
        x[i] = c / w[i];
    //输出
    for (int i = 1; i <= n; i++)
        cout << "重量为" << w[i] << "价值量为" << v[i] << "的物品" << "放入的比例为" << x[i] << endl;
    return 0;
}

程序执行图:

算法日记(十二)之贪心算法_第1张图片

 好啦,关于这个贪心算法下的背包问题就分享到这啦,后面还有一种叫0-1背包的问题,这是贪心算法解决不了的,需要用到动态规划等内容。

本贴为博主亲手整理。如有错误,请评论区指出,一起进步。谢谢大家的浏览.

你可能感兴趣的:(笔记,贪心算法)