编程题四大算法思想(三)——贪心法:找零问题、背包问题、任务调度问题

news2025/1/9 5:00:11

文章目录

  • 贪心法
    • 找零问题(change-making problem)
      • 贪心算法要求
        • 基本思想
        • 适合求解问题的特征
    • 背包问题
      • 0/1背包问题
        • 0/1背包问题——贪心法
      • 分数背包问题
    • 任务调度问题

贪心法

  我在当前情况下,我把我做到最好。我也不管全局如何,整体如何。我就考虑我现在的这一个,或者这一小部分怎样最好。

  • 贪心技术是一种设计算法的通用策略。
  • 贪心技术的基本思想:
    • 基于贪心选择准则,每次得到局部最优的选择。
    • 希望利用局部最后得到全局最优解。
    • 贪心选择性质:局部最优可以得到全局最优。
  • 找到正确的贪心选择准则是设计贪心算法的关键。
    • 不同的贪心选择准则可以得到不同的结果。

打个比方,我现在有几种选择:

学编程、打游戏、读书、去外面玩、去兼职、……

如果我的目的是提高自己的知识水平,那起码对于现在的这些选择来说,我选择“学编程”或者“读书”就是最优的。

只是说当前这一步怎么走是最优的,也并没有去管后面的路怎么走。

比如你说选择“打游戏”,后面可能也会更成功,但是不管这个。

找零问题(change-making problem)

  • 给定无限多不同面额的硬币 d 1 > . . . > d m d_1>...>d_m d1>...>dm,对于总额 n n n,如何找到最少的硬币数目?
  • 问题:目标函数和约束条件是什么?

例如:

d 1 = 25 c , d 2 = 10 c , d 3 = 5 c , d 4 = 1 c ,而且 n = 48 c d_1=25c,d_2=10c,d_3=5c,d_4=1c,而且n=48c d1=25c,d2=10c,d3=5c,d4=1c,而且n=48c

我们可能想,要使得硬币数目最少,那简单啊。

先紧着面额最大的来凑就行了。

先拿个25c的、再拿两个10c的,5c的没法拿,于是再拿3个1c的。

于是得到贪婪解:<1,2,0,3>

我们这个策略就是,很简单,先紧着最大的拿。

但是我们虽然这样做了,而且貌似可行。

但是实际上,它对于大多数情况而言,这样可能是没问题的;但是没法保证所有情况啊,你没法保证对于所有情况、任意某一种情况,这样都没问题。

有一些情况,你这样做,可能就压根不是最优解了。

但是:

  • 对大多数常用的硬币面额都可以得到最优解。
  • 对任意硬币面额,有可能不是最优解。

例如:

d 1 = 25 c , d 2 = 10 c , d 3 = 1 c 而且 n = 30 c d_1=25c,d_2=10c,d_3=1c而且n=30c d1=25c,d2=10c,d3=1c而且n=30c

那么你还按照上面的规则,

先拿个25c的,然后拿五个1c的。——此时是6个硬币。

但实际上我们可以看出,直接拿三个10c的就够了,而且只用3个硬币。

所以可见,我们刚才的那种简单的想法:先紧着大面额的拿。

这种方法,可能在某些情况下没毛病,但是在有些情况下就不对了、不是最优解了。

**那咋办呢。**是不是我的想法、我的策略设计的有问题呢?

那到底咋样弄,才能对于所有情况都能得到最优解呢?

我们可以用回溯法。(不是讲贪心吗,咋又说回溯了?——后面再说这个问题)


  • **贪婪法:**建议通过一系列步骤来构造问题的解,每一步对目前构造的部分解做一个扩展,直到获得问题的完全解。(完全解,不是最优解)
  • 必须满足:可行局部最优不可取消

贪心算法要求

  • 可行的:即它必须满足问题的约束。
  • 局部最优:它是当前步骤中所有可行选择中最佳的局部选择。
  • 不可取消:即选择一旦做出,在算法的后面步骤中就无法改变了。

就像人生中的一些选择一样,就是贪心算法么,每次选的是局部最优,而且选了之后就没法取消了。

  在每一步中,它要求“贪婪”地选择最佳操作,并希望通过一系列局部的最优选择,能够产生一个整个问题的(全局的)最优解。

基本思想

  • 从问题的某一个初始解出发,通过一系列的贪心选择(当前状态下的局部最优选择),逐步逼近给定的目标,尽可能快地求得更好的解。
  • 在贪心算法(greedy method)中也采用逐步构造最优解的方法。在每个阶段,都做出一个按某个评价函数最优的决策,该评价函数最优称为贪心准则(greedy criterion)。
  • 贪心算法的正确性,就是要证明按贪心准则求得的解是全局最优解。
  • 贪心算法不能对所有问题都得到全局最优解。
  • 但是对于许多问题,它能够产生全局最优解。如单源最短路径问题,最小生成树问题等。

适合求解问题的特征

  • **贪心选择性质:**可通过局部最优(贪心)选择达到全局最优解。
    • 通常以自顶向下的方式进行,每次选择后将问题转化为规模更小的子问题。
    • 该性质是贪心法使用成功的保障,否则得到的是近优解。
  • 最优子结构性质:问题的最优解包含它的子问题的最优解
    • 并不是所有具有最优子结构性质的问题都可以采用贪心策略。
    • 往往可以利用最优子结构性质来证明贪心选择性质。

背包问题

  • 0-1背包问题

  给定n种物品和一个背包。物品i的重量是 W i W_i Wi,其价值为 V i V_i Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

0-1背包问题,对于一个物品,0就是不拿它,1就是拿它。

在选择装入背包的物品时,对每种物品只有两种选择,要么装入背包、要么不装入背包。不能将一个物品装入背包多次,也不能只装入某物品的一部分。

  • 背包问题

  与0-1背包问题类似,所不同的是,在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n

背包问题,也叫“分数背包问题”,对于一个物品,物品太大了,背包剩余空间不够了,此时我可以把物品拆下来、把一部分放进去。

0/1背包问题

  • 已知
    • 背包容量C>0
    • n个物品,体积 w i > 0 w_i>0 wi>0,价值 p i > 0   f o r   i = 1 , . . . , n p_i>0\ for\ i=1,...,n pi>0 for i=1,...,n
  • 确定 { 1 , 2 , . . . , n } \{1,2,...,n\} {1,2,...,n}的子集,满足:

m a x ∑ i ∈ A p i , s u b j e c t   t o   ∑ i ∈ A w i ≤ C max\sum_{i∈A}p_i,subject\ to\ \sum_{i∈A}w_i≤C maxiApi,subject to iAwiC

0/1背包问题——贪心法

  • 有以下几种贪心选择准则:

    • 最大价值优先——先选择最值钱的物品。

    紧着最值钱的先往上放。

    • 最小体积优先

    紧着最小体积的先放,想装的多。

    • 最大体积优先

    想着一般大的东西都比较值钱?所以先紧着大件先放?

    • 最大单位价值优先

这四个规则都有一定道理,那我们该选哪种呢?选最大价值优先?选最大单位价值优先?

  • 没有一种方法能保证得到最优解

最大价值优先

image-20230901221752374

lb是重量单位,上面是价钱)

可见,最大价值优先,放进来的不一定是最优解。

最小体积优先

image-20230901221933373

可见,最小体积优先,放进来的也不一定是最优解。

最大体积优先

image-20230901222120953

可见,最大体积优先得到的也不一定是最优解。

最大单位价值优先

image-20230901222244231

可见,这个也不一定能得到最优解。


分数背包问题

  • 对于0/1背包问题,没有最优的贪心算法。
  • 分数背包问题:可以将第i个物品的一部分放入背包。
  • 对于分数背包问题,贪心算法是其不二选择,该算法基于最大单位价值的选择准则。(感觉有点类似于微积分里的微元思想)

这个就没啥好犹豫的了,我先紧着最大单位价值的往里面放,放不下整个物品的时候,我把当前最大单位价值的物品切出来一块往里面放。

这样最后包里放的肯定是价值最大的情况。

  • 贪心算法过程:
    • 降序排序 v i / w i v_i/w_i vi/wi
    • 根据排序次序增加物品,直到这个物品装完,或是超出背包容量。
    • 如果背包没有满,选择下一个物品开始装。

最优解证明

  • 证明

  我们首先假设我们有一个最优解 A 1 A_1 A1,那么我们首先找到 A 1 A_1 A1里面平均价值最高的物品 a m a_m am,然后我们将用商品里面平均价值最高的物品 a 1 a_1 a1 a m a_m am进行全部替换或者部分替换得到解 A 2 A_2 A2,又因为 v 1 w 1 ≥ v m w m \frac{v_1}{w_1}≥\frac{v_m}{w_m} w1v1wmvm,所以 A 2 A_2 A2的总价值高于 A 1 A_1 A1的总价值,这与 A 1 A_1 A1是最优解矛盾,于是得到 A 1 A_1 A1里面包含平均价值最高的物品。


  • 小数背包问题还具有贪心选择性质,用贪心法求解更简单、更快速。
  • 0-1背包问题用贪心法求解不一定能得到最优解。

任务调度问题

  • 9个任务需要调度,每个任务运行时间为3,5,6,10,11,14,15,18,20

如果只有一个处理器,那就没啥说的,每个任务看看按照什么规则往里放就行了,反正最后总时间是一样的。

但是如果有多个处理器呢?

  • 有三个处理器执行这些任务。

当然,对于贪心而言,我们对这一问题也可以有很多种贪心策略。

  • 贪心准则:先运行时间最长的任务。

image-20230901225656081

image-20230901225708372

每次把当前需要运行最长时间的任务,分配给当前任务时间最短的处理器。

image-20230901225829341

因此,三个处理器执行这些任务,花费35分钟时间。

这个解决方法不错,但是我们可能还可以有更好的策略。

  • 另一种贪心准则:优先运行最短任务

image-20230901230002189

image-20230901230054831

这个方式还不如刚才那个,这个需要花费40分钟。

最优解

image-20230901230149638

折腾半天都不是最好的,那我们看看最优解到底是什么样的,如上图所示。

  • 这个解为什么是最优的?

很明显么。因为三个处理器刚好平均分了所有任务的总时长,没有任何的浪费。

  但是,可见,若想得到这样的一种解。你要付出的代价就会很高了。

  有必要么,实际解决一个问题来说,这样去搞,可能没这个必要。你找到最优解了之后,最优解固然能够帮你节约时间;但是不要忽视了,你寻找这个最优解也要花时间。你为了找一个最优解去节约那一点点时间,然后你花了大量的时间在寻找到最优解上,得不偿失。

类似上图中这个最优解,是咋找到的?可能是暴力穷举吧,或者是什么方法。总之很耗时间才能找出来的。

  实际上我就用一种贪心策略,去做,就拉倒了。虽然可能不是最优,但是接近最优差不多就行了。

  对于一些特殊的问题,贪心算法能直接找出其最优解,能直接获取最优解那当然更好了。

  总之贪心算法可能找到的不是最优解,而只是局部最优解;但是它的实现是很简单的,不会耗费太多时间。


  同时,我们在贪心,贪的过程中,也可以利用回溯法的思想,对一些没必要继续探讨下去的情况进行剪枝,而没必要全部贪到底、再去排除。也就是贪心法配合回溯法进行使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/962255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机图形软件(三)6-4 使用GLUT进行显示窗口管理

使用GLUT进行显示窗口管理 我们从使用简化的、最少的操作来显示一个图开始。使用 OpenGL 实用库的第一步是初始化GLUT。该初始化函数也能处理任何命令行变量&#xff0c;但不需要在第一个示例程序中使用参数。完成GLUT初始化的语句是 glutInit (&argc&#xff0c;argv); …

14 mysql bit/json/enum/set 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 bit/json/enum/set 类类型的相关…

Kafka环境搭建与相关启动命令

一、Kafka环境搭建 点击下载kafka_2.11-2.3.1.tgz文件链接 1、上传kafka_2.11-2.3.1.tgz&#xff0c;解压kafka_2.11-2.3.1.tgz&#xff0c;得到kafka_2.11-2.3.1文件夹 1&#xff09;上传 #使用mobaxterm将 kafka_2.11-2.3.1.tgz 传入tools文件夹 #用下面代码进入tools文件…

seq2seq与引入注意力机制的seq2seq

1、什么是 seq2seq&#xff1f; 就是字面意思&#xff0c;“句子 到 句子”。比如翻译。 2、seq2seq 有一些特点 seq2seq 的整体架构是 “编码器-解码器”。 其中&#xff0c;编码器是 RNN&#xff0c;并将 最后一个hidden state&#xff08;隐藏状态&#xff09;【即&…

nacos闪退、密码修改等通用问题

问题1&#xff1a;nacos闪退 解决方案&#xff1a;通常是jdk环境变量配置有问题&#xff0c;nacos获取不到环境变量所以闪退。因为nacos的启动文件会获取JAVA_HOME&#xff0c;如果配置的不对&#xff0c;会直接闪退。如图所示&#xff0c;nacos启动文件最开始就是获取环境…

Rust 学习笔记(持续更新中…)

一、 编译和运行是单独的两步 运行 Rust 程序之前必须先编译&#xff0c;命令为&#xff1a;rustc 源文件名 - rustc main.rs编译成功之后&#xff0c;会生成一个二进制文件 - 在 Windows 上还会生产一个 .pdb 文件 &#xff0c;里面包含调试信息Rust 是 ahead-of-time 编译的…

CleanMyMac X和腾讯柠檬清理功能对比区别介绍

Mac电脑的清理软件款式多样&#xff0c;不同软件之间的功能和清理效果各不相同&#xff0c;那么大家的Mac都用什么清理软件呢&#xff1f;小编看了一篇Mac清理软件介绍的知乎&#xff0c;里面大部分评论用户推荐的主要是两款清理软件&#xff1a;CleanMyMac和腾讯柠檬清理软件。…

Linux挖矿程序清除

1. 找到挖矿进程 2.找到病毒的文件地址 ls -l /proc/进程ID/exe3.删除文件命令 rm -rf 文件地址4.杀死挖矿进程 kill -9 进程ID

【教学类-35-01】学号+姓名+班级(描字帖)A4一页

背景说明&#xff1a; 本学期我带机动班&#xff0c;其中大4班去的频率比较高&#xff0c;与是我用大四班的名单做了一份 “描字帖”&#xff0c;在9月1日第一天见面时&#xff0c;孩子们用记号笔描字帖时&#xff0c;我也可以对这些孩子初步混个眼熟&#xff08;聪明的&#x…

0基础学习VR全景平台篇 第95篇:VR实景智慧导航操作手册

一、实景导航前期准备工作及点位采集 &#xff08;一&#xff09;实景导航前期准备工作 &#xff08;1&#xff09;拍摄设备 1.推荐相机&#xff1a;全画幅的佳能 Canon EOS​ 5D Mark IV 2.搭配镜头&#xff1a;原厂的佳能 Canon EF卡口 8-15mm 全画幅鱼眼镜头 3.三角架 …

基于鱼鹰算法优化的BP神经网络(预测应用) - 附代码

基于鱼鹰算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于鱼鹰算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.鱼鹰优化BP神经网络2.1 BP神经网络参数设置2.2 鱼鹰算法应用 4.测试结果&#xff1a;5.Matlab代码 摘要…

【JavaEE进阶】Spring事务和事务传播机制

文章目录 一. 什么是Spring事务二. Spring中事务的实现1. Spring编程式事务2. 声明式事务2.1 trycatch下事务不会自动回滚的解决方案2.2 Transactional 作用范围2.3 Transactional 参数说明2.4 Transactional 工作原理 三. 事务的隔离级别1. 事务的四大特性2. Spring中设置事务…

15 mysql tiny/meidum/long blob/text 的数据存储

前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 tiny/medium/long blob/text 类…

基于电气特征分析(ESA)的状态监测是如何实现的?

在现代工业和生产环境中&#xff0c;设备的正常运行和高效性对于维持生产的连续性和质量至关重要。然而&#xff0c;设备的故障和损坏可能会导致生产中断、不必要的维修成本以及生产效率的下降。为了应对这些挑战&#xff0c;状态监测技术已成为工业界的重要工具之一&#xff0…

C++之std::search应用实例(一百八十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Redis数据结构总结

Redis 是一款开源的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息代理。Redis 支持多种类型的数据结构&#xff0c;如字符串&#xff08;String&#xff09;、哈希&#xff08;Hashes&#xff09;、列表&#xff08;Lists&#xff09;、集合&…

45、springboot 文件上传到指定磁盘路径 及 上传成功后的文件回显

需求&#xff1a; 写一个文件上传的功能&#xff0c;把文件上传到指定的文件夹。 然后上传成功后的文件回显 ★ Spring Boot对文件上传提供的自动配置支持 Spring Boot的文件上传自动配置主要由 MultipartAutoConfiguration 和 MultipartProperties 两个类组成。MultipartPro…

linux并发服务器 —— 多线程并发(六)

线程概述 同一个程序中的所有线程均会独立执行相同程序&#xff0c;且共享同一份全局内存区域&#xff1b; 进程是CPU分配资源的最小单位&#xff0c;线程是操作系统调度执行的最小单位&#xff1b; Linux环境下&#xff0c;线程的本质就是进程&#xff1b; ps -Lf pid&…

【方案】基于视频与AI智能分析技术的城市轨道交通视频监控建设方案

一、背景分析 地铁作为重要的公共场所交通枢纽&#xff0c;流动性非常高、人员大量聚集&#xff0c;轨道交通需要利用视频监控系统来实现全程、全方位的安全防范&#xff0c;这也是保证地铁行车组织和安全的重要手段。调度员和车站值班员通过系统监管列车运行、客流情况、变电…

MySQL数据库——多表查询(3)-自连接、联合查询、子查询

目录 自连接 查询语法 自连接演示 联合查询 查询语法 子查询 介绍 标量子查询 列子查询 行子查询 表子查询 自连接 通过前面的学习&#xff0c;我们对于连接已经有了一定的理解。而自连接&#xff0c;通俗地去理解就是自己连接自己&#xff0c;即一张表查询多次。…