巧用贪心算法

简介: 五大常用算法(分治、动态规划、贪心、回溯、分支界限(深广优先遍历)),我们之前的文章基本上都有涵盖,唯独差一个贪心算法,本篇文章我们将一起走进贪心算法的妙用。

基本概念

贪心算法(又称贪婪算法),是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解

贪心算法不是对所有问题都能得到整体最优解,但许多问题他能产生整体最优解或者是整体最优解的近似解。

题目特点

我们如何能够确定一道题是否可以用贪心算法求解呢?

因为贪心算法求得的结果不一定是整体最优解,所以我们很难断定它就一定可以用贪心算法。

可以用贪心算法的题目一般具有以下特性

  • 贪心选择性质

    贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。

    动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

    对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

  • 最优子结构性质

    当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。

    问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

贪心算法和动态规划如何选择?

以背包问题为例,给定我们一个有容量限制的背包,和若干不同价值,不同重量的物品,如何选择可以使我们背包内物品价值最大?

这种问题在游戏场景里极为常见,比如自动拾取装备功能,肯定为玩家选择价值最大的装备拾取。

这类问题一般还可以细分为两种类型:

  • 可以拾取物品的一部分 (可以使用贪心,优先拾取性价比高的装备)
  • 物品不可分割,只能拾取,或者不拾取(不可以使用贪心,这类问题也叫0-1背包问题)

image.png

求解思路

一般可以使用贪心算法的题,也可以使用动态规划去做,但是考虑到动态规划的特点是求整体的最优解,在大部分题中贪心要比动态规划时空复杂度更低,也更容易实现。

无论哪些题,贪心算法最重要的是寻找子问题最具性价比的解,也就是局部最优解。

求解过程:

  • 把求解的问题分成若干个子问题。
  • 对每一子问题求解,得到子问题的局部最优解。
  • 把子问题的解局部最优解,合成原来解问题的一个解。

举例:上图背包问题,就可以通过贪心算法来解

步骤:

  • 子问题:装入某件物品
  • 子问题局部最优解:装入性价比最高的物品
  • 合并(所有装入物品价值和)
package com.zhj.interview;
​
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
​
public class Test10 {
    public static void main(String[] args) {
        int capacity = 15;
        int[] weights = {1,1,2,4,12};
        int[] values = {1,2,2,10,4};
        System.out.println("背包最大价值:" + getHighestValue(capacity, weights, values));
    }
​
    public static double getHighestValue(int capacity, int[] weights,int[] values){
​
        //创建物品列表并按照性价比倒序
        List<Item> itemList = new ArrayList<>();
        for(int i=0;i<weights.length;i++){
            itemList.add(new Item(weights[i], values[i]));
        }
        itemList = itemList.stream().sorted(Comparator.comparing(Item::getRatio).reversed()).collect(Collectors.toList());
​
        //背包剩余容量
        int restCapacity = capacity;
        //当前背包物品的最大价值
        double highestValue = 0;
​
        //按照性价比从高到低选择物品
        for(Item item : itemList){
            if(item.weight <= restCapacity){
                highestValue += item.value;
                restCapacity -= item.weight;
            }else{
                //背包装不下完整物品时,选择该件物品的一部分
                highestValue += (double)restCapacity/(double)item.weight * item.value;
                break;
            }
        }
​
        return highestValue;
    }
​
    static class Item {
        private int weight;
        private int value;
        //物品的性价比
        private double ratio;
​
        public Item (int weight, int value){
            this.weight = weight;
            this.value = value;
            this.ratio = (double)value / (double)weight;
        }
​
        public double getRatio() {
            return ratio;
        }
    }
}
目录
相关文章
|
传感器 运维 物联网
蓝牙Mesh网络:连接未来的智能解决方案
蓝牙Mesh网络:连接未来的智能解决方案
2316 12
|
机器学习/深度学习 IDE 开发工具
超越笔记本:JupyterLab 的功能扩展
【8月更文第29天】随着数据科学和机器学习的发展,交互式计算环境的需求也日益增长。Jupyter Notebook 作为这一领域的领头羊,已经得到了广泛的应用。然而,为了满足更加复杂的工作流需求,Jupyter 开发者们推出了 JupyterLab —— 一个下一代的交互式计算环境。本文将探讨 JupyterLab 相对于传统 Jupyter Notebook 的增强功能,并通过具体示例展示这些新特性如何提升工作效率。
594 1
|
11月前
|
存储 人工智能 Serverless
搭建文生图AI系统
随着人工智能的发展,**文本生成图像(文生图)**技术在广告创意、视觉设计、内容营销等领域应用广泛。阿里云通义千问作为先进的大语言模型,不仅具备强大的文本理解能力,还能与图像生成技术结合,实现根据文本描述自动生成高质量图像。 本博客将展示如何使用通义千问与阿里云的其他产品(如函数计算、API 网关、对象存储 OSS)搭建一个简单的文生图系统,实现用户输入文本并生成相应图像的功能。
663 6
|
算法 索引
【算法与数据结构】深入二叉树实现超详解(全源码优化)
【算法与数据结构】深入二叉树实现超详解(全源码优化)
248 1
|
Web App开发 前端开发 JavaScript
跨浏览器兼容性指南:解决常见的前端兼容性问题
跨浏览器兼容性是前端开发中至关重要的概念。由于不同浏览器(如Chrome、Firefox、Safari等)在实现Web标准方面存在差异,网页在不同浏览器上可能会呈现不一致的结果。因此,确保网页在各种浏览器上都能正确显示和运行,是提供良好用户体验、扩大受众范围以及增强网站可访问性的关键。
|
机器学习/深度学习 数据采集 存储
PyTorch 小课堂!一篇看懂核心网络模块接口(下)
小伙伴们大家好呀~前面的文章中(PyTorch 小课堂开课啦!带你解析数据处理全流程(一)、PyTorch 小课堂!带你解析数据处理全流程(二)),我们介绍了数据处理模块。而当我们解决了数据处理部分,接下来就需要构建自己的网络结构,从而才能将我们使用数据预处理模块得到的 batch data 送进网络结构当中。接下来,我们就带领大家一起再认识一下 PyTorch 中的神经网络模块,即 torch.nn。
1189 0
PyTorch 小课堂!一篇看懂核心网络模块接口(下)
|
弹性计算 负载均衡 容灾
|
5天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。