JavaScript 贪心算法(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),因为我们必须创建一个二维数组来将开始时间和结束时间存储在一起。

下面是上述方法的实现。

// 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. 
    function printMaxActivities(s,f,n) 
    { 
        let i, j; 
        document.write("Following activities are selected : n"); 
          
        // The first activity always gets selected 
        i = 0; 
        document.write(i+" "); 
          
        // Consider rest of the activities 
        for (j = 1; j < n; j++) 
        { 
          
             // 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]) 
             { 
                  document.write(j+" "); 
                  i = j; 
              } 
        } 
    } 
      
    // Driver program to test above function 
    let s = [1, 3, 0, 5, 8, 5] 
    let f = [2, 4, 6, 7, 9, 9] 
    let n = s.length; 
    printMaxActivities(s, f, n); 
      
    // This code is contributed by avanitrachhadiya2155  

输出
选择以下活动
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 中的排序)。一旦我们对活动进行排序,我们就应用相同的算法。

下图是上述方法的说明: 

下面是上述方法的实现:

/* JavaScript program for activity selection problem 
 when input activities may not be sorted.*/
function MaxActivities(arr, n){ 
    let selected = []; 
      
    // Sort jobs according to finish time 
       Activity = Activity.sort(function(a,b) { 
    return a[1] - b[1]; 
    }); 
      
    // The first activity always gets selected 
    let i = 0 
    selected.push(arr[i]); 
  
    for(let j=1;j<n;j++){ 
      /*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.push(arr[j]); 
          i = j; 
      } 
    } 
    return selected; 

// Driver code 
Activity = [[5, 9], [1, 2], [3, 4], [0, 6],[5, 7], [8, 9]]; 
n = Activity.length; 
selected = MaxActivities(Activity, n); 
document.write("Following activities are selected : <br>") 
console.log(selected) 
for(let i = 0;i<selected.length;i++) 
    document.write("("+selected[i]+"), ") 

输出
选定以下活动:
(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、打印选择的活动,存储在答案向量中

下面是上述方法的实现: 

// javascript program for the above approach 
  
 // Pair class 
class Pair 

    constructor(first,second) 
    { 
        this.first = first; 
          this.second = second; 
    } 

  
function SelectActivities(s,f) 

    // Vector to store results. 
    let ans = []; 
    
    // Minimum Priority Queue to sort activities in 
    // ascending order of finishing time (f[i]). 
    let p = []; 
    
    for (let i = 0; i < s.length; i++) { 
      // Pushing elements in priority queue where the 
      // key is f[i] 
      p.push(new Pair(f[i], s[i])); 
    } 
    p.sort(function(a,b){return a.first-b.first;}); 
    
    let it = p.shift(); 
    let start = it.second; 
    let end = it.first; 
    ans.push(new Pair(start, end)); 
    
    while (p.length!=0) { 
      let itr = p.shift(); 
      if (itr.second >= end) { 
        start = itr.second; 
        end = itr.first; 
        ans.push(new Pair(start, end)); 
      } 
    } 
    document.write( 
      "Following Activities should be selected. <br>"); 
    
    for(let itr of ans.values()) { 
      document.write( 
        "Activity started at: " + itr.first 
        + " and ends at  " + itr.second+"<br>"); 
    } 

  
// Driver Code 
let s=[1, 3, 0, 5, 8, 5 ]; 
let f=[2, 4, 6, 7, 9, 9 ]; 
// Function call 
SelectActivities(s, f); 
  
  
// This code is contributed by rag2127  

输出
应选择以下活动。

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

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

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

相关文章

路由器的工作原理

5.1路由器的工作原理 如图5-1所示配置IP地址&#xff08;此处省略&#xff0c;请读者自行配置&#xff09;&#xff0c;配置完成后&#xff0c;我们在R1上分别ping 12.1.1.2 、23.1.1.2、23.1.1.3&#xff0c;我们可以发现&#xff0c;在R1上ping 12.1.1.2可以通&#xff0c;但…

光电耦合器:航天航空领域的先进连接技术

光电耦合器作为一种关键的电子连接器&#xff0c;在航天航空领域扮演着重要角色。本文将深入探讨光电耦合器在航天航空领域的应用及其技术特点。 光电耦合器在航天航空领域的应用 光电耦合器作为一种高可靠性、高速传输、抗干扰能力强的连接器&#xff0c;在航天航空领域有着广…

释放视频潜力:Topaz Video AI for mac/win 一款全新的视频增强与修复利器

在数字时代&#xff0c;视频已经成为我们记录生活、分享经历的重要方式。然而&#xff0c;有时候我们所拍摄的视频可能并不完美&#xff0c;可能存在模糊、噪点、抖动等问题。这时候&#xff0c;就需要一款强大的视频增强和修复工具来帮助我们提升视频质量&#xff0c;让它们更…

MT8781安卓核心板_MTK联发科Helio G99核心板规格参数

MT8781安卓核心板采用先进的台积电6纳米级芯片生产工艺&#xff0c;配备高性能Arm Cortex-A76处理器和Arm Mali G57 GPU&#xff0c;加上LPDDR4X内存和UFS 2.2存储&#xff0c;在处理速度和数据访问速度上都有着出色的表现。 MT8781还支持120Hz显示器&#xff0c;无需额外的DSC…

资深开发推荐的IDEA 插件

开发如虎添翼 工欲善其事&#xff0c;必先利其器。想要提升编程开发效率&#xff0c;必须选择一款顺手的开发工具&#xff0c;插件不在多&#xff0c;而在精&#xff0c;作为从业10年的程序员&#xff0c;我目前用到这十几个插件&#xff0c;在平时开发&#xff0c;代码review…

C#WPF数字大屏项目实战01--开发环境与项目创建

1、学习目标 -界面布局 &#xff0c;- 模板调整&#xff0c;- 控件封装&#xff0c;- 图表&#xff0c;- 通信对接&#xff0c;- 动态更新 2、开发环境 开发工具&#xff1a;Visual Studio-2022-17.8.6-Community 运行时框架&#xff1a;.Net 6或Framework 4.5以上 UI框…

SpringCloud-OpenFeign

一 OpenFeign是什么?有什么用? 以往我们是通过 RestTemplate 发起远程调用&#xff0c;如下: 存在问题如下&#xff1a; 代码可读性差&#xff0c;编程体验不统一参数复杂URL难以维护 Feign 是一个声明式的 http 客户端&#xff0c;其作用就是用来把我们解决上述问题的~ 二…

技术云图:大数据新手的云端征途

前段时间的一次面试中&#xff0c;在面试快要结束的时候&#xff0c;我问了面试官一个我认为对大数据开发岗位很重要的问题&#xff1a; 我作为一个大数据开发岗位的新人&#xff0c;大数据方向要学习的知识和技术实在太多了&#xff0c;想请问&#xff1a;您认为大数据开发岗位…

初出茅庐的小李博客之使用立创开发板(ESP32)连接到EMQX Platform【MQTT TLS/SSL 端口连接】

介绍 手上有一块立创开发板&#xff0c;本着不吃灰的原则把它用起来&#xff0c;今天就来用它来连接上自己部署的MQTT服务器进行数据通信。 硬件&#xff1a;立创开发板 开发环境&#xff1a;Arduino IDE Win11 MQTT 平台&#xff1a;EMQX Platform 立创开发板介绍&#xff1…

论文总结:Grasp-Anything: Large-scale Grasp Dataset from Foundation Models

目录 一、论文摘要 二、Grasp-Anything数据集 A. 场景生成 B. 抓取姿势标注 ​编辑 C. Grasp-Anything统计 D. Grasp-Anything对社区的帮助 三、实验 A. 零样本抓取检测 B. 机器人评估 C. 野外抓取检测 D. 讨论 四、总结 论文&#xff1a;https://arxiv.org/pdf/2…

Kafka系列之高频面试题

基础 简介 特点&#xff1a; 高吞吐、低延迟&#xff1a;kafka每秒可以处理几十万条消息&#xff0c;延迟最低只有几毫秒&#xff0c;每个Topic可以分多个Partition&#xff0c;Consumer Group对Partition进行Consumer操作可扩展性&#xff1a;Kafka集群支持热扩展持久性、可…

STM32启动过程分析

Keil堆栈设置注意事项 一、启动模式 复位方式&#xff1a;上电复位、硬件复位、软件复位 从地址0x0000 0000处取出堆栈指针MSP的初始值&#xff0c;该值就是栈顶地址。从地址0x0000 0004处取出程序计数器指针PC的初始值&#xff0c;该值指向复位后执行的第一条指令。 说白了就…

基于模板匹配的信用卡数字识别

文章目录 一、项目介绍二、模板匹配的原理三、模板匹配的步骤模板图片处理信用卡图片处理进行模板匹配 一、项目介绍 模板识别&#xff08;Template Matching&#xff09;是一种基于图像匹配的技术&#xff0c;用于在较大图像中识别和定位小图像&#xff08;模板&#xff09;。…

YOLO目标检测:框架技术原理和代码实现

Dream推荐 适读人群 &#xff1a;本书适合对YOLO目标检测感兴趣、了解深度学习相关概念的算法工程师、软件工程师等人员阅读。 全面&#xff1a;涵盖6个常用目标检测框架&#xff08;YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOX、YOLOv7&#xff09;的发展状况、技术原理和代码实…

【Spring EL<一>✈️ 】SL 表达式的应用

目录 &#x1f378;前言 &#x1f37b;一、Spring EL 1.1 定义 1.2 常见使用方式 &#x1f37a;二、项目案例 2.1 实现一个简单的案例 2.2 创建注解 2.3 切面类实现 2.4 创建测试接口 2.5 测试 &#x1f379;三、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;前段时间…

32. 【Java教程】集合

在前面的小节中&#xff0c;我们学习了数组&#xff0c;本小节学习的集合同样用于存放一组数据&#xff0c;我们将学习什么是集合、集合的应用场景 &#xff0c;在应用场景部分我们将对比 Java 数组与集合的区别&#xff0c;还将系统介绍 Java 集合的架构&#xff0c;也将结合实…

【观察】数字化生存时代已来临,能源转型如何实现“再升级”?

20多年前&#xff0c;尼古拉斯尼葛洛庞帝在《数字化生存》一书中预言&#xff1a;“数字化生存是现代社会中以新技术为基础的新的生存方式。” 随着数字经济的蓬勃发展&#xff0c;尼葛洛庞帝的预言逐渐被验证。今天&#xff0c;新技术带来的数字化和智能化正全方位影响着经济…

【赠书第27期】向AI提问的艺术:提示工程入门与应用

文章目录 前言 1 问题的构建 1.1 明确性与具体性 1.2 结构化与层次性 1.3 相关性与针对性 2 提问的技巧 2.1 简洁明了 2.2 避免歧义 2.3 使用自然语言 3 与AI的互动策略 3.1 耐心与理解 3.2 逐步引导 3.3 反馈与调整 4 总结与展望 5 推荐图书 6 粉丝福利 前言 …

定时器与PWM的LED控制

目录 一、基础概念定时器定时器类型定时器特性 PWM定义占空比原理 二、实验1.LED周期性亮灭定时器TIM2配置GPIO引脚设置工程相关参数配置Keil编写程序 2.LED呼吸灯(PWM)呼吸灯原理Keil编写程序Keil虚拟示波器&#xff0c;观察 PWM输出波形设置点击setup&#xff0c;并设置观察引…

Sapphire开发日志(三)

任务描述 本周实现并封装了模型的运行&#xff0c;需要在前端安装依赖的库&#xff0c;编写对应的处理函数。同时需要能够展示出抠图效果。 依赖与环境配置 尝试在前端接入并运行onnx。 在前端运行onnx依赖于onnxruntime-web这个包&#xff0c;这个包可以在浏览器进行模型推…