当前位置: 首页 > news >正文

算法(三)——贪心算法

文章目录

    • 定义
    • 基本原理
    • 基本思路
    • 优缺点
      • 优点
      • 缺点
    • 经典案例及解析
      • 找零问题
        • 问题描述
        • 贪心思路
        • 算法解析
        • 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代码示例 定义 贪心算法是指在求解问题时&#xff0c;总是做出在当前…...

LeetCode 704.二分查找

LeetCode 704.二分查找 思路&#x1f9d0;&#xff1a; 在本篇以及之后几篇的博客中&#xff0c;博主将会用二分法进行解答&#xff0c;以此巩固二分题型。二分法一般用于具有二段性的数据中使用。比如该题为有序数组&#xff0c;需要我们查找一个目标值target&#xff0c;分析…...

Linux介绍与安装CentOS 7操作系统

什么是操作系统 操作系统&#xff0c;英⽂名称 Operating System&#xff0c;简称 OS&#xff0c;是计算机系统中必不 可少的基础系统软件&#xff0c;它是 应⽤程序运⾏以及⽤户操作必备的基础环境 ⽀撑&#xff0c;是计算机系统的核⼼。 操作系统的作⽤是管理和控制计算机系…...

使用 rbenv 切换 Ruby 版本

1. 查看当前 Ruby 版本 首先&#xff0c;查看当前系统中安装的 Ruby 版本&#xff1a; ruby -v如果你已经安装了 rbenv&#xff0c;可以列出通过 rbenv 安装的 Ruby 版本&#xff1a; rbenv versions2. 安装 Ruby 版本 如果你想安装新的 Ruby 版本&#xff0c;使用以下命令…...

C语言(结构体练习)

设计一个结构体,存放一个学员信息并显示&#xff0c;存放两个学员信息&#xff0c;算他们的平均分。 #include <stdio.h> #include <string.h>// 定义结构体 typedef struct {char name[50];float score; } Student;// 函数声明 void display(Student student); f…...

你了解网络层的 ICMP 吗?

你了解网络层的 ICMP 吗&#xff1f; 一. 什么是 ICMP二. ICMP 的工作原理三. ICMP 的结构四. ICMP 的常见应用五. ICMP 的局限性与安全性六. 总结 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神…...

清理C盘小记

突然C盘就爆满了&#xff0c;想当初还是给他预留了120G的空间&#xff0c;感觉到现在也不够用了&#xff0c;担心出现死机的情况就赶紧进行了清理。有一说一&#xff0c;清理回收站是真的有用。 参考&#xff1a;C盘清理指南&#xff0c;清理出30G起&#xff0c;超详细总结&am…...

Excel中如何消除“长短款”

函数微调可以可以实施&#xff0c;简单且易于操作的气球&#x1f388;涨缩更妙。 (笔记模板由python脚本于2024年12月17日 06:19:13创建&#xff0c;本篇笔记适合用Excel操作数据的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Fre…...

超越 RAG 基础:AI 应用的高级策略

作者&#xff1a;来自 Elastic Elastic Platform Team 我们最近与 Cohere 举办的虚拟活动深入探讨了检索增强生成 (retrieval augmented generation - RAG) 的世界&#xff0c;重点讨论了在概念验证阶段之后构建 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允许远程连接 …...

零衍门户国际化:助力拓展全球视野

概述 零衍系统管理平台统一门户管理&#xff0c;支持门户看板灵活配置&#xff0c;同时提供场景化的门户模板&#xff0c;丰富的门户组件&#xff0c;可协助用户快速搭建企业专属门户。 随着零衍产品的不断成熟&#xff0c;国际化需求日益增多&#xff0c;客户期望零衍门户可…...

mysql免安装版配置教程

一、将压缩包解压至你想要放置的文件夹中&#xff0c;注意&#xff1a;绝对路径中要避免出现中文 二、在解压目录下新建my.ini文件&#xff0c;已经有的就直接覆盖 my.ini文件内容 [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirD:\\tools\\mysql-8.1.0-win…...

kafka的处理的一些问题 消费延迟

kafka的处理的一些问题 消费者客户端不但没有背压而且内存充足&#xff0c;但产生的消费延迟越来越大在Kafka的Leader副本宕机时 消费者客户端不但没有背压而且内存充足&#xff0c;但产生的消费延迟越来越大 比如我们这个kakfa集群一共有3个Broker节点 TOp1有5个分区&#xf…...

旅游创业,千益畅行,开启新的旅游模式!

在当今旅游市场蓬勃发展的时代&#xff0c;旅游卡项目如一颗新星闪耀登场&#xff0c;而千益畅行旅游卡服务更是其中的佼佼者&#xff0c;为广大旅游爱好者带来了全新的旅游体验与机遇。 一、旅游卡项目是如何运作的呢&#xff1f; 千益畅行旅游卡服务的运作模式犹如一部精心…...

集成自然语言理解服务,让应用 “听得懂人话”

如今&#xff0c;应用程序智能化已成趋势&#xff0c;开发者想要实现智能化&#xff0c;那么首先需要赋予应用理解自然语言的能力&#xff0c;使其能够准确地听懂人话&#xff0c;进而响应用户需求&#xff0c;并提供一系列智能化服务。比如用户语音控制应用程序帮忙订票&#…...

利用notepad++删除特定关键字所在的行

1、按组合键Ctrl H&#xff0c;查找模式选择 ‘正则表达式’&#xff0c;不选 ‘.匹配新行’ 2、查找目标输入 &#xff1a; ^.*关键字.*\r\n (不保留空行) ^.*关键字.*$ (保留空行)3、替换为&#xff1a;&#xff08;空&#xff09; 配置界面参考下图&#xff1a; ​​…...

[HNOI2002] 营业额统计 STL - set集合

文章目录 [HNOI2002] 营业额统计题目描述样例输入 #1样例输出 #1 提示题解相关知识点set [HNOI2002] 营业额统计 STL - set解题 题目描述 Tiger 最近被公司升任为营业部经理&#xff0c;他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出…...

fastAPI接口(普通流式响应和大模型流式响应)

1. 流式输出和非流失输出&#xff1a; 大模型的流式输出&#xff08;Streaming Output&#xff09;和非流式输出&#xff08;Non-streaming Output&#xff09;是指在生成文本或其他输出时&#xff0c;如何将结果返回给用户或下游系统。 流式输出 (Streaming Output)&#xf…...

Linux系统安装node.js

一、node官网下载想要的node版本 https://nodejs.org/en/download/package-manager 二、将tar.xz文件解压 tar -xvf node-vxxx.tar.xz 三、改文件夹的名字&#xff0c;改成nodejs mv node-xxx nodejs 四、复制nodejs文件&#xff0c;并上传到linux 服务器 /usr/local 目录下…...

《解决两道有趣的编程问题:交替数字和与简单回文》

在编程的世界里&#xff0c;算法和逻辑的挑战无处不在。今天&#xff0c;我们将用 Python 来解决两道有趣的编程问题&#xff0c;分别是计算交替数字和以及生成简单回文。 一、交替数字和&#xff08;Alternating Sum of Numbers&#xff09; 1. 问题描述 给定一系列整数&am…...

2412d,d的8月会议

原文 总结 替换D的逃逸分析 Rikki说,他一个月前曾与Dennis讨论过简化D的逃逸分析,但没有结果.在BeerConf上,他再次提起了它,Dennis说他一直在考虑它. Rikki也与Walter谈过这件事,Walter曾说过DIP1000并没有完全如期工作,且有点太复杂了. 因此,Rikki想讨论按D逃逸分析方法替…...

WEB自动化测试(selenium工具)框架、面试题

一、什么是web自动化测试 让程序员代替人为去验证web项目功能的过程 二、什么web项目适合自动化测试 1)需求变动不频繁 测试脚本的稳定性决定了自动化测试的维护成本。如果软件需求变动过于频繁&#xff0c;测试人员需要根据变动的需求来更新测试用例以及相关的测试脚本&…...

前端自动化部署之ssh2和ssh2-sftp-client

ssh2-sftp-client 本身是一个专门用于处理 SFTP文件操作的库&#xff0c;它不直接提供执行远程命令的功能。但是可以通过它的底层依赖库 ssh2 实现执行命令的功能。 以下是实现方法和示例代码&#xff1a; 方法一&#xff1a;使用 ssh2 执行远程命令 ssh2 是 ssh2-sftp-client…...

python pandas 优化内存占用(一)

最近我用python处理excel&#xff0c;使用的是pandas库&#xff0c;我发现pandas库非常占用内存&#xff0c;一直想研究下如何优化pandas的内存占用&#xff0c;但一直没腾出空来&#xff0c;最近终于有时间研究一把了&#xff0c;我先把优化方法写上&#xff0c;如果你想了解更…...

FutureCompletableFuture实战

1. Callable&Future&FutureTask介绍 直接继承Thread或者实现Runnable接口都可以创建线程&#xff0c;但是这两种方法都有一个问题就是&#xff1a;没有返回值&#xff0c;也就是不能获取执行完的结果。因此java1.5就提供了Callable接口来实现这一场景&#xff0c;而Fu…...

Loki 微服务模式组件介绍

目录 一、简介 二、架构图 三、组件介绍 Distributor&#xff08;分发器&#xff09; Ingester&#xff08;存储器&#xff09; Querier&#xff08;查询器&#xff09; Query Frontend&#xff08;查询前端&#xff09; Index Gateway&#xff08;索引网关&#xff09…...

peerDependencies对等依赖

在 package.json 中平时常用的有字段有 dependencies 和 devDependencies&#xff0c;但 peerDependencies 平时都没咋看到过&#xff0c;今天具体讲讲 peerDependencies 的作用 一、什么是对等依赖 peerDependencies 可以翻译为“对等依赖”或“同行依赖”。这个术语在 npm …...

贪心算法 part01

class Solution { public:int maxSubArray(vector<int>& nums) {int result INT32_MIN;int count 0;for (int i 0; i < nums.size(); i) {count nums[i];if (count > result) { // 取区间累计的最大值&#xff08;相当于不断确定最大子序终止位置&#xff…...