[数据结构与算法]贪心算法(原理+代码)

news2024/12/23 1:32:48

博主介绍:✌专研于前后端领域优质创作者、本质互联网精神开源贡献答疑解惑、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!

👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

目录

一、什么是贪心算法

贪心算法的一般流程如下:

二、常见应用算法

Prim算法:贪心算法的一种常见应用是Prim算法。Prim算法的基本思想是从一个初始顶点开始,每次选择一条边,将一个新的顶点纳入生成树中,直到所有的顶点都被纳入生成树。

活动选择问题(Activity Selection Problem):

三、小结:

最后欢迎三连点赞、关注、收藏哦! 

一、什么是贪心算法

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最优解的策略,希望通过一系列局部最优的选择最终达到全局最优。贪心算法通常用于优化问题,其中在每个阶段都做出局部最优的选择,希望通过这种方式达到全局最优解。

贪心算法的主要特点是它对解的选择没有显式的规定,而是通过一系列的局部选择来达到整体最优。每一步都选择当前状态下的最优解,而不考虑未来的影响。 

贪心算法的一般流程如下:

  1. 问题建模: 将问题抽象成一系列的局部最优选择。
  2. 选择策略: 确定每一步的选择策略,即如何在当前状态下做出最优的选择。
  3. 解决问题: 通过贪心策略逐步解决问题,直到达到全局最优解或者近似最优解。

虽然贪心算法在一些问题中非常有效,但并不是所有问题都适合使用贪心算法。在某些情况下,贪心算法可能无法得到全局最优解,因为它不进行回溯。因此,在使用贪心算法时,需要仔细分析问题的特性,确保贪心策略能够达到预期的最优解。典型的贪心算法应用包括最小生成树、单源最短路径、任务调度等。

二、常见应用算法

Prim算法:贪心算法的一种常见应用是Prim算法。Prim算法的基本思想是从一个初始顶点开始,每次选择一条边,将一个新的顶点纳入生成树中,直到所有的顶点都被纳入生成树。

#include <iostream>
#include <climits>
using namespace std;

#define V 5  // 顶点数

int minKey(int key[], bool mstSet[]) {
    int min = INT_MAX, min_index;

    for (int v = 0; v < V; v++) {
        if (!mstSet[v] && key[v] < min) {
            min = key[v];
            min_index = v;
        }
    }

    return min_index;
}

void printMST(int parent[], int graph[V][V]) {
    cout << "Minimum Spanning Tree (Prim):" << endl;
    for (int i = 1; i < V; i++)
        cout << "Edge: " << parent[i] << " - " << i << " Weight: " << graph[i][parent[i]] << endl;
}

void primMST(int graph[V][V]) {
    int parent[V];
    int key[V];
    bool mstSet[V];

    // 初始化所有键值为无穷大,都未包含在生成树中
    for (int i = 0; i < V; i++) {
        key[i] = INT_MAX;
        mstSet[i] = false;
    }

    // 选择第一个顶点作为起始点
    key[0] = 0;
    parent[0] = -1;

    for (int count = 0; count < V - 1; count++) {
        int u = minKey(key, mstSet);

        mstSet[u] = true;

        for (int v = 0; v < V; v++) {
            if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v]) {
                parent[v] = u;
                key[v] = graph[u][v];
            }
        }
    }

    printMST(parent, graph);
}

int main() {
    int graph[V][V] = { {0, 2, 0, 6, 0},
                        {2, 0, 3, 8, 5},
                        {0, 3, 0, 0, 7},
                        {6, 8, 0, 0, 9},
                        {0, 5, 7, 9, 0} };

    primMST(graph);

    return 0;
}

执行结果:

活动选择问题(Activity Selection Problem):

假设有一个教室,需要安排一系列活动,每个活动都有一个开始时间和结束时间。活动之间不能重叠,即同一时间教室只能进行一个活动目标是选择尽可能多的活动使得它们不会相互冲突,即在给定时间内进行尽可能多的非重叠活动。 

C++代码:

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

// 首先声明一个活动结构体,包含活动开始时间和结束时间两个变量
struct Activity {
    int start, finish;
};

// 按照活动结束时间升序排序的比较函数
bool compare(Activity a, Activity b) {
    return (a.finish < b.finish);
}

// 贪心算法解决活动选择问题
void printMaxActivities(Activity activities[], int n) {
    // 按照结束时间升序排序
    sort(activities, activities + n, compare);

    cout << "Selected Activities:\n";

    // 第一个活动总是被选中
    int i = 0;
    cout << "(" << activities[i].start << ", " << activities[i].finish << "), ";

    // 遍历剩余活动
    for (int j = 1; j < n; j++) {
        // 如果当前活动的开始时间大于等于上一个选中活动的结束时间,选择当前活动
        if (activities[j].start >= activities[i].finish) {
            cout << "(" << activities[j].start << ", " << activities[j].finish << "), ";
            i = j;
        }
    }
}

int main() {
    // 示例活动数据(活动开始实践和结束时间)
    Activity activities[] = {{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}};
    int n = sizeof(activities) / sizeof(activities[0]);

    // 调用贪心算法解决活动选择问题
    printMaxActivities(activities, n);

    return 0;
}

活动按照结束时间升序排序,然后使用贪心算法选择尽可能多的不重叠活动。这个算法的时间复杂度为O(n log n),其中n是活动的数量。 

执行结果:

三、小结:

1. 基本思想:

  • 贪心算法是一种在每一步选择中都采取当前状态下最优解的策略,希望通过一系列局部最优的选择达到全局最优。
  • 贪心策略通常不进行回溯,一旦做出选择就不再改变。

2. 适用条件:

  • 问题具有最优子结构性质:问题的最优解可以通过子问题的最优解推导得到。
  • 贪心选择性质:每一步的选择都是当前状态下的最优解,即局部最优。

3. 过程步骤:

  • 建模: 将问题抽象成一系列局部最优的选择。
  • 选择策略: 确定每一步的选择策略,即如何在当前状态下做出最优的选择。
  • 解决问题: 通过贪心策略逐步解决问题,直到达到全局最优解或者近似最优解。

4. 优缺点:

  • 优点: 算法简单、高效,适用于一些问题,尤其是最优子结构和贪心选择性质明显的情况。
  • 缺点: 不适用于所有问题,可能得不到全局最优解,只能得到局部最优解或者近似最优解。

5. 注意事项:

  • 贪心算法的适用性需要仔细分析问题的性质,确保贪心策略能够达到预期的最优解。
  • 在一些问题中,贪心算法可以作为求解问题的一部分,而不是整个问题的解决方案。

最后欢迎三连点赞、关注、收藏哦! 

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

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

相关文章

HarmonyOS-Stage模型开发概述

Stage模型开发概述 基本概念 下图展示了Stage模型中的基本概念。 图1 Stage模型概念图 UIAbility组件和ExtensionAbility组件 Stage模型提供UIAbility和ExtensionAbility两种类型的组件&#xff0c;这两种组件都有具体的类承载&#xff0c;支持面向对象的开发方式。 UIAbili…

力扣hot100 无重复字符的最长子串 双指针 滑动窗口 哈希

Problem: 3. 无重复字符的最长子串 文章目录 思路Code 思路 &#x1f468;‍&#x1f3eb; 参考 Code ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( 1 ) O(1) O(1) class Solution {public int lengthOfLongestSubstring(String s){if (s null ||…

Quartus生成烧录到FPGA板载Flash的jic文件

简要说明&#xff1a; Altera的FPGA芯片有两种基本分类&#xff0c;一类是纯FPGA&#xff0c;另一类是FPGASoc&#xff08;System on chip)&#xff0c;也就是FPGAHPS&#xff08;Hard Processor System&#xff0c;硬核处理器&#xff09;&#xff0c;对应两种Flash烧录方式&a…

算法模板 2.差分

差分和前缀和是逆运算 差分数组可以将对a数组任意区间的加/减操作优化到O ( 1 ) 一维差分 797. 差分 - AcWing题库 #include <bits/stdc.h> using namespace std; const int N 100010; int a[N], b[N];void insert(int l, int r, int c){b[l] c; //表示l以后&#x…

消息中间件之RocketMQ源码分析(三)

RocketMQ中的Consumer启动流程 RocketMQ客户端中有两个独立的消费者实现类分别为DefaultMQPullConsumer和DefaultMQPushConsumer&#xff0c; DefaultMQPullConsumer DefaultMQPullConsumer,该消费者使用时需要用户主动从Broker中Pull消息和消费消息&#xff0c;提交消费位点…

Altium Designer的学习

PCB设计流程 1.新建空白工程&#xff1a; 创建一个新的工程 新建四个文件&#xff0c;并且保存&#xff1a; 每次打开文件时&#xff0c;打开以.PrjPcb结尾的文件 2.元件符号的创建&#xff1a; 在绘制图形的时候设置成10mil,为了在原理图中显得不那么大。 在绘制引脚的时候设…

外星人入侵(python)

前言 代码来源《python编程从入门到实践》Eric Matthes 署 袁国忠 译 使用软件&#xff1a;PyCharm Community Editor 2022 目的&#xff1a;记录一下按照书上敲的代码 alien_invasion.py 游戏的一些初始化设置&#xff0c;调用已经封装好的函数方法&#xff0c;一个函数的…

将vant地区数据改为label value children格式

以下代码放到nodejs中运行 a.js文件内容&#xff0c;vant的数据&#xff0c;来自import { areaList } from vant/area-data&#xff0c;形如&#xff1a; const fs require(fs);const a require(./a.js);const b transformData(a); fs.writeFileSync(./b.js, JSON.string…

STM32G4 系列命名规则

STM32G4产品线 基础型系列STM32G4x1 具有入门级模拟外设配置&#xff0c;单存储区Flash&#xff0c;支持的Flash存储器容量范围从32到512KB。 增强型系列STM32G4x3 与基本型器件相比具有更多数量的模拟外设&#xff0c;以及双存储区Flash&#xff0c;Flash存储器容量也提高…

如何在Windows系统使用Plex部署影音服务与公网访问本地资源【内网穿透】

文章目录 1.前言2. Plex网站搭建2.1 Plex下载和安装2.2 Plex网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通…

Spring-mybatis

怎样通过Spring整合Mybatis来实现业务 目录 1.导入依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency>&l…

快乐学Python,如何正确使用pandas处理时间类型的数据?

在日常的数据分析工作中&#xff0c;常常会有根据日期来对数据进行分析。比如我们需要通过用户的下单时间来分析用户在不同时间段对商品的喜好&#xff1b;如通过访问日志的访问时间来分析系统的访问周期和负载&#xff0c;为不同时间段的资源调配提供依据&#xff1b;如通过用…

vit细粒度图像分类(六)TransFC学习笔记

1.摘要 从判别局部区域学习特征表示在细粒度视觉分类中起着关键作用。利用注意机制提取零件特征已成为一种趋势。然而&#xff0c;这些方法有两个主要的局限性:第一&#xff0c;它们往往只关注最突出的部分&#xff0c;而忽略了其他不明显但可区分的部分。其次&#xff0c;他们…

2024不可不会的StableDiffusion之拼接各组件(五)

1. 引言 在之前的文章中&#xff0c;我介绍了如何安装扩散器库diffuser用以生成 AI 图像和构成stable diffusion的各个关键组件&#xff0c;即 CLIP 文本编码器、VAE 和 U-Net。在这篇文章中&#xff0c;我们将尝试把这些关键组件放在一起&#xff0c;并详细展示生成图像的扩散…

如何在Shopee菲律宾市场进行选品:策略和建议

在Shopee菲律宾市场进行选品时&#xff0c;卖家需要采取一系列策略和建议&#xff0c;以确保他们的产品能够在这个市场上取得成功。这篇文章将介绍一些关键的策略和建议&#xff0c;帮助卖家更好地了解市场趋势、关注热销品类、满足消费者需求、创新营销手段、优化供应链管理、…

大数据分析|从七个特征理解大数据分析

文献来源&#xff1a;Saggi M K, Jain S. A survey towards an integration of big data analytics to big insights for value-creation[J]. Information Processing & Management, 2018, 54(5): 758-790. 下载链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1…

如何进行有效的Shopee新店选品

在Shopee平台上开设新店是一个令人兴奋的时刻&#xff0c;但是在开始销售之前&#xff0c;进行有效的选品是至关重要的一步。选品的质量和策略将直接影响你的市场竞争力和销售业绩。下面是一些建议&#xff0c;可以帮助你进行有效的Shopee新店选品。 先给大家推荐一款shopee知虾…

❤ 做一个自己的AI智能机器人吧

❤ 做一个自己的AI智能机器人 看了扣子&#xff08;coze&#xff09;的模型&#xff0c;字节基于chatgpt搭建的一个辅助生成AI的网站&#xff0c;感觉蛮有意思&#xff0c;看了掘金以后&#xff0c;于是动手自己也实现了一个。 官网 https://www.coze.cn/ 进入的网站 1、 创…

算法模板 1.前缀和

前缀和&#xff1a;以O(1)的时间求解一段区间的和&#xff0c;空间复杂度O(n) 一维前缀和 795. 前缀和 - AcWing题库 #include <bits/stdc.h> using namespace std; const int N 100010; int a[N],s[N]; int main(){int n,m;scanf("%d%d",&n,&m);fo…

跟着cherno手搓游戏引擎【15】DrawCall的封装

目标&#xff1a; Application.cpp:把渲染循环里的glad代码封装成自己的类&#xff1a; #include"ytpch.h" #include "Application.h"#include"Log.h" #include "YOTO/Renderer/Renderer.h" #include"Input.h"namespace YO…