算法(三)——贪心算法
文章目录
- 定义
- 基本原理
- 基本思路
- 优缺点
- 优点
- 缺点
- 经典案例及解析
- 找零问题
- 问题描述
- 贪心思路
- 算法解析
- java代码示例
- 活动选择问题
- 问题描述
- 贪心思路
- 算法解析
- java代码示例
- 车辆路径问题
- 问题描述
- 贪心思路
- 算法分析
- java代码示例
定义
贪心算法是指在求解问题时,总是做出在当前来看是最好的选择,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。在一些特定的问题中,贪心算法可以通过逐步构建最优解来实现全局最优。
基本原理
贪心算法的核心在于它所具有的贪心选择性质。这意味着在对问题求解时,每一步都可以做出一个在当前看来是最优的选择,而不用考虑整体的最优解。
例如,在找零问题中,假设我们有无限量的面值为 25 美分、10 美分、5 美分和 1 美分的硬币,要找给顾客 63 美分的零钱。贪心算法的做法是,每次都选择尽可能大面值的硬币,先选 2 个 25 美分,剩下 13 美分,再选 1 个 10 美分,剩下 3 美分,接着选 3 个 1 美分。这种每一步都选择当前最优(面值最大的硬币)的方式就是贪心选择。
基本思路
从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。
但是存在问题:
不能保证求得的最后解是最佳的;
不能用来求最大或最小解问题;
只能求满足某些约束条件的可行解的范围。
优缺点
优点
简单易懂:
贪心算法通常非常直观和易于理解,解决问题的思路简单直接。
局部最优解:
贪心算法通过每一步选择当前最优解(局部最优解),尝试构建全局最优解。
高效:
贪心算法的时间复杂度通常较低,适合解决某些大规模问题。常见的时间复杂度为 O(nlogn) 或 O(n)。
应用广泛:
贪心算法在诸如图论(如最小生成树、最短路径)、任务调度、资源分配等多个领域有广泛的应用。
缺点
局限性:
贪心算法并不总能找到问题的最优解。它依赖于每一步的局部最优选择,可能会错过全局最优解。例如,背包问题的贪心算法不能保证找到最优解。
问题依赖性:
贪心算法只有在某些特定类型的问题(满足贪心选择性质和最优子结构性质)中才能有效工作。对于不满足这些性质的问题,贪心算法无法保证最优解。
分析复杂:
对于某些问题,证明贪心算法的正确性和最优性可能较为复杂,需要仔细的数学推导和验证。
无回溯:
贪心算法一旦做出选择,就不会回溯或改变决定。因此,一旦做出错误的选择,就无法修正。
经典案例及解析
找零问题
问题描述
给定一些面额不同的硬币,如1元、5元、10元,要找零n元,找零的硬币数量要尽可能少。
贪心思路
在每一步选择中,选择面额最大的硬币,直到找零的总金额达到n
算法解析
先初始化一个空列表,用于存储找零的硬币。从面额最大的硬币开始,将尽可能多的这个硬币加入列表,直到总金额超过n。如果总金额等于n,算法结束。否则,将面额减小到次大的硬币,重复上述步骤。
java代码示例
import java.util.ArrayList;
import java.util.List;public class CoinChangeGreedy {public static void main(String[] args) {int n = 28; // 需要找零的金额int[] coins = {10, 5, 1}; // 可用的硬币面额List<Integer> result = getMinimumCoins(n, coins);// 输出结果System.out.println("所需硬币数量: " + result.size());System.out.println("硬币面额: " + result);}public static List<Integer> getMinimumCoins(int n, int[] coins) {List<Integer> result = new ArrayList<>();// 遍历硬币面额,从大到小for (int coin : coins) {// 尽可能多地使用当前面额的硬币while (n >= coin) {result.add(coin);n -= coin;}}return result;}
}
本贪心算法适用于硬币面额满足贪心选择性质的情况。在本例中,10 和 5 的面额对于任何情况都能进行贪心选择,因此算法是有效的。如果硬币面额不同,比如 {1, 3, 4},则贪心策略可能无法获得最优解。
活动选择问题
问题描述
给定一系列活动,每个活动都有开始时间和结束时间,目标是选择尽可能多的互不相交的活动。
贪心思路
在每一步选择中,选择结束时间最早的活动,可以腾出更多时间给其他活动。
算法解析
1.排序:首先根据活动的结束时间对活动进行排序。
2.选择活动:从第一个活动开始,选择结束时间最早的活动,并继续选择所有不与已选活动重叠的活动。
java代码示例
import java.util.*;class Activity {int start; // 活动的开始时间int end; // 活动的结束时间Activity(int start, int end) {this.start = start;this.end = end;}
}public class ActivitySelection {// 方法:选择尽可能多的互不相交的活动public static List<Activity> selectActivities(List<Activity> activities) {// 1. 按照结束时间排序activities.sort(Comparator.comparingInt(a -> a.end));List<Activity> selectedActivities = new ArrayList<>();// 2. 选择活动int lastEndTime = -1; // 上一个被选择的活动的结束时间,初始为负值for (Activity activity : activities) {// 如果当前活动的开始时间大于或等于上一个选择的活动的结束时间if (activity.start >= lastEndTime) {// 选择当前活动selectedActivities.add(activity);lastEndTime = activity.end; // 更新结束时间}}return selectedActivities;}public static void main(String[] args) {// 创建一些活动对象 (开始时间, 结束时间)List<Activity> activities = new ArrayList<>();activities.add(new Activity(1, 4));activities.add(new Activity(3, 5));activities.add(new Activity(0, 6));activities.add(new Activity(5, 7));activities.add(new Activity(8, 9));activities.add(new Activity(5, 9));// 调用选择活动的方法List<Activity> selectedActivities = selectActivities(activities);// 打印选择的活动System.out.println("选中的活动如下:");for (Activity activity : selectedActivities) {System.out.println("活动开始时间: " + activity.start + ", 活动结束时间: " + activity.end);}}
}
车辆路径问题
问题描述
有一组客户点和一个中心仓库,目标是找到一条路径,使得所有客户都被访问,并且路径总长度最短。
贪心思路
从仓库出发,选择离当前位置最近的客户点,重复此过程直到所有客户都被访问。
算法分析
从仓库出发,选择距离仓库最近的客户。访问该客户,然后选择距离当前客户最近的未被访问的客户。重复这个过程,直到所有客户都被访问完。
java代码示例
import java.util.*;
public class GreedyTSP {// 定义一个二维数组表示客户和仓库的坐标static class Point {int x, y;Point(int x, int y) {this.x = x;this.y = y;}// 计算两点之间的欧几里得距离double distanceTo(Point other) {return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));}}public static void main(String[] args) {// 仓库的坐标Point warehouse = new Point(0, 0);// 客户的坐标List<Point> customers = Arrays.asList(new Point(2, 3),new Point(5, 2),new Point(8, 8),new Point(6, 7),new Point(1, 6));// 调用贪心算法获取访问路径List<Point> path = greedyTSP(warehouse, customers);// 输出路径System.out.println("访问顺序:");for (Point p : path) {System.out.println("客户位置: (" + p.x + ", " + p.y + ")");}}// 贪心算法实现public static List<Point> greedyTSP(Point warehouse, List<Point> customers) {List<Point> path = new ArrayList<>();Set<Point> visited = new HashSet<>();Point current = warehouse;// 将仓库添加到路径path.add(current);// 循环直到所有客户都被访问while (visited.size() < customers.size()) {Point nearestCustomer = null;double minDistance = Double.MAX_VALUE;// 寻找最近的未访问客户for (Point customer : customers) {if (!visited.contains(customer)) {double dist = current.distanceTo(customer);if (dist < minDistance) {minDistance = dist;nearestCustomer = customer;}}}// 将找到的最近客户添加到路径,并标记为已访问if (nearestCustomer != null) {path.add(nearestCustomer);visited.add(nearestCustomer);current = nearestCustomer; // 更新当前客户为最近客户}}return path;}
}
以上是我对贪心算法学习过程中的一部分内容进行了总结,我一直秉持着只有先了解学习过这些算法思想和原理之后才能对它的应用掌握得更深入,后续还会继续学习总结一系列算法思想,不定时进行总结。
相关文章:
算法(三)——贪心算法
文章目录 定义基本原理基本思路优缺点优点缺点 经典案例及解析找零问题问题描述贪心思路算法解析java代码示例 活动选择问题问题描述贪心思路算法解析java代码示例 车辆路径问题问题描述贪心思路算法分析java代码示例 定义 贪心算法是指在求解问题时,总是做出在当前…...
LeetCode 704.二分查找
LeetCode 704.二分查找 思路🧐: 在本篇以及之后几篇的博客中,博主将会用二分法进行解答,以此巩固二分题型。二分法一般用于具有二段性的数据中使用。比如该题为有序数组,需要我们查找一个目标值target,分析…...
Linux介绍与安装CentOS 7操作系统
什么是操作系统 操作系统,英⽂名称 Operating System,简称 OS,是计算机系统中必不 可少的基础系统软件,它是 应⽤程序运⾏以及⽤户操作必备的基础环境 ⽀撑,是计算机系统的核⼼。 操作系统的作⽤是管理和控制计算机系…...
使用 rbenv 切换 Ruby 版本
1. 查看当前 Ruby 版本 首先,查看当前系统中安装的 Ruby 版本: ruby -v如果你已经安装了 rbenv,可以列出通过 rbenv 安装的 Ruby 版本: rbenv versions2. 安装 Ruby 版本 如果你想安装新的 Ruby 版本,使用以下命令…...
C语言(结构体练习)
设计一个结构体,存放一个学员信息并显示,存放两个学员信息,算他们的平均分。 #include <stdio.h> #include <string.h>// 定义结构体 typedef struct {char name[50];float score; } Student;// 函数声明 void display(Student student); f…...
你了解网络层的 ICMP 吗?
你了解网络层的 ICMP 吗? 一. 什么是 ICMP二. ICMP 的工作原理三. ICMP 的结构四. ICMP 的常见应用五. ICMP 的局限性与安全性六. 总结 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神…...
清理C盘小记
突然C盘就爆满了,想当初还是给他预留了120G的空间,感觉到现在也不够用了,担心出现死机的情况就赶紧进行了清理。有一说一,清理回收站是真的有用。 参考:C盘清理指南,清理出30G起,超详细总结&am…...
Excel中如何消除“长短款”
函数微调可以可以实施,简单且易于操作的气球🎈涨缩更妙。 (笔记模板由python脚本于2024年12月17日 06:19:13创建,本篇笔记适合用Excel操作数据的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Fre…...
超越 RAG 基础:AI 应用的高级策略
作者:来自 Elastic Elastic Platform Team 我们最近与 Cohere 举办的虚拟活动深入探讨了检索增强生成 (retrieval augmented generation - RAG) 的世界,重点讨论了在概念验证阶段之后构建 RAG 应用程序的关键注意事项。我们的演讲者是 Elastic 的首席解…...
[shader]【图形渲染】【unity】【游戏开发】 Shader数学基础2-认识点和矢量
在计算机图形学和Shader编程中,点和矢量是两种常见且基础的数学对象。它们在空间中的作用和性质是理解图形渲染的关键。本篇文章将深入探讨点(Point)和矢量(Vector)的定义、特性以及它们之间的关系。 1. 点(Point)的定义 在数学和计算机图形学中,**点(Point)**用于…...
微软开源Python Markdown转换工具
分享一个microsoft开源的Python工具——markitdown,轻松将各类文件转换为Markdown格式。 markitdown支持的文件格式 PDF(.pdf)PowerPoint(.pptx)Word(.docx)Excel(.xlsx)图片(支持EXIF元数据和OCR识别)音频(支持EXIF元数据和语音转录)HTML(包括对Wikipedia...
安装与配置MongoDB 6.0以支持远程连接
安装与配置MongoDB 6.0以支持远程连接 目录 安装curl工具下载并导入MongoDB 6.0 PGP密钥向APT导入MongoDB 6.0版软件包的资源链接安装MongoDB依赖libssl1.1安装MongoDB启动并检查MongoDB服务状态进入MongoDB Shell交互式执行环境设置MongoDB开机自启配置MongoDB允许远程连接 …...
零衍门户国际化:助力拓展全球视野
概述 零衍系统管理平台统一门户管理,支持门户看板灵活配置,同时提供场景化的门户模板,丰富的门户组件,可协助用户快速搭建企业专属门户。 随着零衍产品的不断成熟,国际化需求日益增多,客户期望零衍门户可…...
mysql免安装版配置教程
一、将压缩包解压至你想要放置的文件夹中,注意:绝对路径中要避免出现中文 二、在解压目录下新建my.ini文件,已经有的就直接覆盖 my.ini文件内容 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirD:\\tools\\mysql-8.1.0-win…...
kafka的处理的一些问题 消费延迟
kafka的处理的一些问题 消费者客户端不但没有背压而且内存充足,但产生的消费延迟越来越大在Kafka的Leader副本宕机时 消费者客户端不但没有背压而且内存充足,但产生的消费延迟越来越大 比如我们这个kakfa集群一共有3个Broker节点 TOp1有5个分区…...
旅游创业,千益畅行,开启新的旅游模式!
在当今旅游市场蓬勃发展的时代,旅游卡项目如一颗新星闪耀登场,而千益畅行旅游卡服务更是其中的佼佼者,为广大旅游爱好者带来了全新的旅游体验与机遇。 一、旅游卡项目是如何运作的呢? 千益畅行旅游卡服务的运作模式犹如一部精心…...
集成自然语言理解服务,让应用 “听得懂人话”
如今,应用程序智能化已成趋势,开发者想要实现智能化,那么首先需要赋予应用理解自然语言的能力,使其能够准确地听懂人话,进而响应用户需求,并提供一系列智能化服务。比如用户语音控制应用程序帮忙订票&#…...
利用notepad++删除特定关键字所在的行
1、按组合键Ctrl H,查找模式选择 ‘正则表达式’,不选 ‘.匹配新行’ 2、查找目标输入 : ^.*关键字.*\r\n (不保留空行) ^.*关键字.*$ (保留空行)3、替换为:(空) 配置界面参考下图: …...
[HNOI2002] 营业额统计 STL - set集合
文章目录 [HNOI2002] 营业额统计题目描述样例输入 #1样例输出 #1 提示题解相关知识点set [HNOI2002] 营业额统计 STL - set解题 题目描述 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出…...
fastAPI接口(普通流式响应和大模型流式响应)
1. 流式输出和非流失输出: 大模型的流式输出(Streaming Output)和非流式输出(Non-streaming Output)是指在生成文本或其他输出时,如何将结果返回给用户或下游系统。 流式输出 (Streaming Output)…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
