python 贪心算法(Greedy Algo)

        贪婪是一种算法范式,它逐步构建解决方案,始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 

如果问题具有以下属性,则可以使用贪心法解决优化问题: 

        每一步,我们都可以做出当前看来最好的选择,从而得到整个问题的最优解。 

        如果贪婪算法可以解决某个问题,那么它通常会成为解决该问题的最佳方法,因为贪婪算法通常比动态规划等其他技术更有效。但贪婪算法并不总是适用。例如,Fractional Knapsack问题可以使用Greedy来解决,但是0-1 Knapsack问题不能使用Greedy来解决。

以下是一些贪婪算法的标准算法:

1)Kruskal的最小生成树(MST): 
        在 Kruskal 算法中,我们通过一条一条地选取边来创建 MST。贪心选择是选择在目前构建的 MST 中不会引起循环的最小权重边

2)Prim的最小生成树: 
        在 Prim 的算法中,我们也是通过逐条选取边来创建 MST。我们维护两个集合:一组已包含在 MST 中的顶点和一组尚未包含的顶点。贪心选择是选择连接两个集合的最小权重边

3)Dijkstra的最短路径: 
        Dijkstra 算法与 Prim 算法非常相似。最短路径树是逐边构建的。我们维护两个集合:一组已包含在树中的顶点和一组尚未包含的顶点。贪心选择是选择连接两个集合并且位于从源到包含尚未包含的顶点的集合的最小权重路径上的边

4)霍夫曼编码: 
        霍夫曼编码是一种无损压缩技术。它将可变长度位代码分配给不同的字符。贪心选择是将最小位长的代码分配给最常见的字符。

        贪心算法有时也用于获得硬优化问题的近似值。例如,旅行商问题是一个 NP 难问题。这个问题的贪婪选择是每一步都选择距离当前城市最近的未访问过的城市。这些解决方案并不总是产生最佳的最优解决方案,但可用于获得近似最优的解决方案。

这里让我们看一个可以使用贪心算法解决的问题

问题:
        您将获得n项活动及其开始和结束时间。选择一个人可以执行的最大活动数,假设一个人一次只能从事一项活动。 

例子:  

输入: start[] = {10, 12, 20}, finish[] = {20, 25, 30}
输出: 0
解释:一个人最多可以执行一项活动。

输入: start[] = {1, 3, 0, 5, 8, 5}, finish[] = {2, 4, 6, 7, 9, 9};
输出: 0 1 3 4
解释:一个人最多可以执行四项活动。
可以执行的最大活动集 是 
{0, 1, 3, 4} [ 这些是 start[] 和 finish[] 中的索引

方法:要解决该问题,请遵循以下想法:

        贪心选择是总是选择剩余活动中完成时间最短的下一个活动,并且开始时间大于或等于先前选择的活动的结束时间。我们可以根据活动的完成时间对活动进行排序,以便我们始终将下一个活动视为完成时间最短的活动

请按照给定的步骤解决问题:

1、根据活动的完成时间对活动进行排序 
2、从排序数组中选择第一个活动并打印它 
3、对排序数组中的剩余活动执行以下操作
4、如果此活动的开始时间大于或等于先前选择的活动的结束时间,则选择此活动并打印
注意:在实现中,假设活动已经按照完成时间排序,否则时间复杂度将上升到 O(N*log(N)),辅助空间将上升到 O(N),因为我们必须创建一个二维数组来将开始时间和结束时间存储在一起。

下面是上述方法的实现。 

# Python3 program for activity selection problem. 
  
# The following implementation assumes that the activities 
# are already sorted according to their finish time 
  
# Prints a maximum set of activities that can be done  
# by a single person, one at a time 
def printMaxActivities(s, f): 
    n = len(f) 
    print("Following activities are selected") 
  
    # The first activity is always selected 
    i = 0
    print(i, end=' ') 
  
    # Consider rest of the activities 
    for j in range(1, n): 
  
        # If this activity has start time greater than 
        # or equal to the finish time of previously 
        # selected activity, then select it 
        if s[j] >= f[i]: 
            print(j, end=' ') 
            i = j 
  
  
# Driver code 
if __name__ == '__main__': 
    s = [1, 3, 0, 5, 8, 5] 
    f = [2, 4, 6, 7, 9, 9] 
  
    # Function call 
    printMaxActivities(s, f) 
  
# This code is contributed by Nikhil Kumar Singh  

输出
选择以下活动
0 1 3 4
时间复杂度: O(N)
辅助空间: O(1)

贪婪选择如何适用于根据完成时间排序的活动? 
        假设给定的活动集为 S = {1, 2, 3, …n},活动按完成时间排序。贪婪选择总是选择活动 1。为什么活动 1 总是提供最佳解决方案之一?

        我们可以通过证明如果存在另一个解 B 且第一个活动不是 1,则也存在一个与活动 1 大小相同的解 A 作为第一个活动。设B选择的第一个活动为k,则总存在A = {B – {k}} U {1}。

注: B 中的活动是独立的,并且 k 的完成时间是所有活动中最小的。由于 k 不为 1,所以 finish(k) >= finish(1))

当给定的活动未排序时如何实施? 
        我们为活动创建一个结构/类。我们按完成时间对所有活动进行排序(请参阅C++ STL 中的排序)。一旦我们对活动进行排序,我们就应用相同的算法。

下图是上述方法的说明: 

下面是上述方法的实现:

''' Python program for activity selection problem 
 when input activities may not be sorted.'''
  
  
def MaxActivities(arr, n): 
    selected = [] 
  
    # Sort jobs according to finish time 
    Activity.sort(key=lambda x: x[1]) 
  
    # The first activity always gets selected 
    i = 0
    selected.append(arr[i]) 
  
    for j in range(1, n): 
  
        '''If this activity has start time greater than or 
           equal to the finish time of previously selected 
           activity, then select it'''
        if arr[j][0] >= arr[i][1]: 
            selected.append(arr[j]) 
            i = j 
    return selected 
  
  
# Driver code 
if __name__ == '__main__': 
    Activity = [[5, 9], [1, 2], [3, 4], [0, 6], [5, 7], [8, 9]] 
    n = len(Activity) 
  
    # Function call 
    selected = MaxActivities(Activity, n) 
    print("Following activities are selected :") 
    print(selected[0], end = ""); 
    for i in range (1, len(selected)): 
        print(",", end = " ") 
        print(selected[i], end = "") 
  
# This code is contributed by kshitijjainm  

输出
选定以下活动:
(1、2)、(3、4)、(5、7)、(8、9)
时间复杂度: O(N log N),如果输入活动可能无法排序。当输入活动始终排序时,需要 O(n) 时间。
辅助空间: O(1)

使用优先级队列的活动选择问题:
我们可以使用 Min-Heap 来获取完成时间最短的活动。Min-Heap 可以使用优先级队列实现

请按照给定的步骤解决问题:

1、创建优先级队列(最小堆)并将活动推入其中。
2、将优先级队列的顶部推入答案向量,并将变量start设置为第一个活动的开始时间,将变量end 3、设置为该活动的结束时间
4、当优先级不为空时,执行以下操作:
        4.1、取出优先级队列的顶部并检查
        4.2、如果此活动的开始时间大于或等于最后选择的活动的结束时间,则将此活动推入答案向量
        4.3、不然就忽略它
 5、打印选择的活动,存储在答案向量中

下面是上述方法的实现: 

# Python3 program for activity selection problem 
# when input activities may not be sorted. 
from heapq import heappop, heappush 
  
# Function to select activites 
  
  
def SelectActivities(s, f): 
    ans = [] 
    p = [] 
  
    # Pushing elements in the list 
    for i, j in zip(s, f): 
        heappush(p, (j, i)) 
  
    it = heappop(p) 
    start = it[1] 
    end = it[0] 
    ans.append(it) 
  
    # Sorting process 
    while p: 
        it = heappop(p) 
        if it[1] >= end: 
            start = it[1] 
            end = it[0] 
            ans.append(it) 
  
    print("Following Activities should be selected.\n") 
    for f, s in ans: 
        print(f"Activity started at {s} and ends at {f}") 
  
  
# Driver code 
if __name__ == "__main__": 
    s = [1, 3, 0, 5, 8, 5] 
    finish = [2, 4, 6, 7, 9, 9] 
  
    # Function call 
    SelectActivities(s, finish) 
  
# This code is contributed by kraanzu.  

输出
应选择以下活动。

活动开始于:1 结束于:2
活动开始于:3 结束于:4
活动开始于:5 结束于:7
活动开始于:8 结束于:9
时间复杂度: O(N * log N)
辅助空间: O(N) 

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

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

相关文章

3d网渲100比本地渲染快吗?渲染100邀请码1a12

3D网渲是一种基于云计算的技术,它将渲染工作交由云端进行,以网渲平台渲染100为例,比起本地渲染,它有以下一些优势。 1、本地渲染受硬件限制,只能一台电脑渲染一张图,而渲染100有充足的服务器数量&#xf…

QT 音乐播放器【一】 显示音频级别指示器

文章目录 效果图概述代码总结 效果图 概述 QMediaPlayer就不介绍了,就提供了一个用于播放音频和视频的媒体播放器 QAudioProbe 它提供了一个探针,用于监控音频流。当音频流被捕获或播放时,QAudioProbe 可以接收到音频数据。这个类在需要访问…

C/C++动态内存管理(new与delete)

目录 1. 一图搞懂C/C的内存分布 2. 存在动态内存分配的原因 3. C语言中的动态内存管理方式 4. C内存管理方式 4.1 new/delete操作内置类型 4.2 new/delete操作自定义类型 1. 一图搞懂C/C的内存分布 说明: 1. 栈区(stack):在…

计组雨课堂(5)知识点总结——备考期末复习(xju)

在汇编语言源程序中,“微指令语句"不是常见的组成部分,因为微指令通常是在硬件层面进行处理的,而不是在汇编语言层面。因此,不属于汇编语言源程序的是"微指令语句”。在汇编语言中,组成指令语句和伪指令语句…

直方图滤波、粒子滤波、卡尔曼滤波

三者都是基于贝叶斯滤波。 粒子滤波和直方图滤波不要求高斯分布,可解决非线性 卡尔曼滤波要求高斯分布且线性。扩展卡尔曼滤波为了解决非线性问题,利用泰勒展开进行一阶近似。 直方图滤波就是贝叶斯滤波的直观实现。自动驾驶定位算法-直方图滤波(Hist…

【Linux终端探险】:从入门到熟练,玩转基础命令的秘密(二)

文章目录 🚀Linux基础命令(二)🌈1. 寻找目录/文件命令⭐2. 创建文件命令👊3. 网络接口查询命令❤️4. 打包命令💥5. 解压命令 上期回顾: 🔥🔥🔥【Linux终端探…

19、matlab信号预处理中的中值滤波(medfilt1()函数)和萨维茨基-戈雷滤波滤(sgolayfilt()函数)

1、中值滤波:medfilt1()函数 说明:一维中值滤波 1)语法 语法1:y medfilt1(x) 将输入向量x应用3阶一维中值滤波器。 语法2:y medfilt1(x,n) 将一个n阶一维中值滤波器应用于x。 语法3:y medfilt1(x,n…

2024年项目任务管理软件大盘点:12款值得一试的主流工具

12款优秀的项目任务管理软件:PingCode、Worktile、AIrTable、ClickUp、Teambition、Asana、Todoist、TAPD、Monday.com、Notion、Microsoft Project、Trello。 任务管理软件对于生活繁忙的人来说极为重要。它帮助用户有效跟踪他们需要完成的各项任务,包括…

牛客热题:没有重复数字的全排列

📟作者主页:慢热的陕西人 🌴专栏链接:力扣刷题日记 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 文章目录 牛客热题:没有重复数字的全排列题目链接方…

LeetCode - 二分查找(Binary Search)算法集合(Python)[左右边界|旋转数组|双列表]

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/139419653 二分查找,也称为折半查找,是一种在有序数组中查找特定元素的高效算法。其基本原理是将待搜索的区间分成两半&am…

小猪APP分发:如何轻松进行在线封装APP

你是否曾经因为需要封装一个新版本的APP而感到头疼?传统的封装过程往往繁琐且耗时。但是,别担心,现在有了“小猪APP分发”,一切变得如此简单。 小猪APP分发www.appzhu.net是一个专门提供在线APP封装服务的平台。无论你是开发者还…

Thingsboard物联网网关接入ThingsBoard物联网平台的操作说明

本文包含关于如何配置ThingsBoard 平台和连接钡铼技术R40设备的说明。ThingsBoard平台是一个用于数据收集、处理、可视化和设备管理的开源物联网平台。它通过行业标准MQTT协议实现设备连接。ThingsBoard结合了可扩展性、容错性和性能,因此您永远不会丢失数据。 4G L…

因为侵权只能重装系统后的必备软件List

前因:自从上次被adobe警告了后,又被source insight警告了… 正好得升级系统,不如直接清清爽爽的重装系统吧,一切回到解放前,重新配置电脑, 该文记载了我办公必备的宝贝软件们 1、Firefox-火狐浏览器&#x…

18、matlab信号生成与预处理--剔除异常值:hampel()函数

1、语法 说明:对输入向量x应用Hampel滤波器来检测和去除异常值。 1)y hampel(x) 参数:x:输入信号 y:预处理的输出信号 对于x的每个样本,函数计算由样本及其周围的六个样本组成的窗口的中位数,每边三…

PHPStudy(xp 小皮)V8.1.1 通过cmd进入MySQL命令行模式

PHPStudy是一个PHP开发环境集成包,可用在本地电脑或者服务器上,该程序包集成最新的PHP/MySql/Apache/Nginx/Redis/FTP/Composer,一次性安装,无须配置即可使用。MySQL MySQL是一个关系型数据库管理系统,由瑞典 MySQL A…

元宇宙NFG结合IPO线上营销模型合理降税

在当今快速演进的互联网和区块链技术背景下,我们见证了从移动端购物到区块链热潮,再到如今市场竞争日趋激烈的变革。尤其是在2024年这个关键节点,许多平台为了吸引用户,推出了各种创新的商业模式。然而,如何在这样的环…

ssh远程转发22端口,使用shell工具进行连接|使用服务器地址ssh连接本地ubuntu|端口映射

☆ 问题描述 我在内网主机中,使用docker创建了多个虚拟机,我希望能通过我的公网ip服务器端口进行shell访问 ★ 解决方案 我创建一个新的虚拟机为例 1. 创建并打开容器 docker run -itd --name test ubuntu2. 进入容器 docker exec -it test /bin/b…

react 中使用 swiper

最近项目中需要用到轮播图,我立马想起了 swiper ,那么本文就来带大家体验一下如何在 React 中使用这个插件,使用的是 函数组 hooks 的形式。 需求非常简单,就是一个可以自动播放、点击切换的轮播图(跑马灯&#xff0…

心理咨询系统|心理咨询系统成品开发功能

心理咨询系统开发后端设计是一个复杂且精细的过程,涉及多个关键领域的专业知识和技术。本文将详细探讨心理咨询系统开发后端设计的各个方面,包括系统架构、数据库设计、接口开发、安全性保障以及性能优化等。 首先,我们来谈谈系统架构。在心理…

小白跟做江科大32单片机之光敏传感器控制蜂鸣器

代码部分 1.思路 通过光敏电阻,控制蜂鸣器的发声 2.butter.h代码 #ifndef _BUTTER__H #define _BUTTER__H void butter_Init(void); void butter_on(void); void butter_off(void); #endif 3.butter.c代码 #include "stm32f10x.h" void butter…