【数据结构】贪心算法

一.贪心算法的定义

        贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解

        贪心算法的结果是最优解的最好近似。

优点:简单,高效。

缺点:可能不是正确的或最优的解

二.引例

当一个问题具有最优子结构性质时,可以用动态规划求解。也可以用贪心算法来求解。

哈夫曼编码:每次选择集合中权值最小的两个子树构成一棵树。

思想:贪心选择思想。

三.贪心算法的基本步骤与实现

1.建立数学模型来描述问题;

2.把求解的问题分成若干个子问题;

3.对每一个子问题求解,得到子问题的局部最优解;

4.把子问题的局部最优解合成原来问题的解。

四.贪心算法的应用

1.活动安排问题

(1)问题描述

1)有n个活动;

2)活动j在$s_j$时刻开始,$f_j$时刻结束;

3)如果两个活动不重叠,则这两个活动是可以兼容的;

4)目标:找到相互兼容的最大活动子集

(2)活动相容性:

设有n个活动的集合E={1,2,……,n},其中,每个活动都要求使用同一资源,如会场等。

而在同一时间内,只有一个活动能够使用该资源。

每个活动i都有一个要求使用该资源的起始时间$s_i$和一个结束时间$f_i$,且$s_i$<$f_i$

如果选择了活动i,则它在半开时间区间[$s_i$,$f_i$)内占用资源。

若区间[$s_i$,$f_i$)与区间[$s_j$,$f_j$)不相交,则称活动i与活动j相容。

(3)贪心策略:

先安排结束时间最早的活动,可以使得剩余的时间极大化,从而安排更多的活动。

(4)伪代码:

1.将所有活动按照结束时间从小到大排列;

2.扫描所有活动的开始时间与结束时间,若扫描到活动i的开始时间早于最近安排的活动j的结束时间,则不安排活动i,否则,安排活动i。

(5)代码:

int greedySelector(int s[],int f[],bool a[],int n){//n代表事件个数,bool类型的数组a表示活动i是否被安排//各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排序int i=0,j=0,count=0;//i表示处理的第i个活动,j表示刚刚安排的活动,count记录安排活动的数量//初始化a[i]=true;//安排第一个事件j=0;count++;for(i=1;i<n;i++){if(s[i]>f[j]) {a[i]=true;j = i;count++;}else{a[i]=false;}}return count;
}

 

(6)其他贪心策略:

1)最早开始时间

按照开始时间$s_i$非递减排序

2)最早结束时间 

按照结束时间$s_i$非递减排序

3)最短间隔

按照间隔长度$f_i-s_i$非递减排序

4)最小冲突

对于每个活动,计算该活动的冲突活动数$c_j$,并按照$c_j$非递减排序

(7)证明贪心算法对于活动安排问题的求解是整体最优解:

对于活动安排问题来说:

最优解即为:使得相容集合的规模最大

数学归纳法进行证明)

证明:

设E={1,2,……,n}活动集合(集合有序)

且按照活动安排结束时间递增排序,即:活动1具有最早的完成时间

假设:活动安排中有一个包含贪心选择的最优解

设A$\subseteq$E是该问题的一个最优解,且集合A也有序,对于A中的活动,将其表示为{$k_1,k_2,...,k_j$},则有活动的开始时间集合S={$s[k_1],s[k_2],...s[k_j]$},以及结束时间集合F=$\{f[k_1],f[k-2],...,f[k_j]\}$

找到一个集合A,首先:A是问题最优解;其次,A是贪心选择出来的集合。

当k=1时,A即为所求。

当k!=1时,设$B=$$A-\{k_1\}\cup\{1\}=\{1,k_2,k_3,...,k_j\}$

由于,$f[1]\leqslant f[k]$,将集合A更改之后,整个集合仍然相容,元素个数也没有改变,集合B也是最优解。

同理,以及将A中的元素替换,由于贪心选择的原理,每次选择结束时间最早的事件,则替换之后,集合仍然是相容的,将所有元素均替换为贪心选择的元素,则集合既是贪心选择的结果,也是最优解,即:贪心选择出的集合是最优解,得证。#

五.贪心算法的基本要素

1.贪心选择性质

所求问题的整体最优解可以通过一系列局部最优的选择达到。

用数学归纳法证明,通过每步的贪心选择,最终可以得到问题的整体最优解。

2.最优子结构性质

当一个问题的最优解包含其子问题的最优解,称此问题具有最优子结构性质。

问题的最优子结构性质是该问题可以用动态规划算法或者贪心算法求解的关键特征。

3.贪心算法和动态规划差别

动态规划:自底向上

贪心算法:从开始逐次迭代

0-1背包问题:

问题描述:

给定n种物品和一个背包。物品i的重量是$w_i $,其价值为$v_i$,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大。

背包问题:

问题描述:

与0-1背包问题类似,所不同的是,在选择物品i装入背包时,可以选择物品的一部分,而不一定要全部装入背包中。

这两类问题都具有最优子结构性质,但是背包问题可以用贪心算法求解,而0-1背包问题却不能用贪心算法求解。

用贪心算法求解背包问题的基本步骤:

1.计算每种物品单位重量的价值$\frac{v_i}{w_i}$;

2.依据贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包; 

3.若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包;

4.依照此策略一直进行下去,直到背包装满为止。

代码实现:

#include <iostream>
using namespace std;struct node{float weight;float value;int number;
};int greedySelector(int s[],int f[],bool a[],int n);
float knapsack(float c,int n,float v[],float w[],float x[]);
int partition(struct node a[],int first,int end);
void quickSort(struct node a[],int first,int end);int main() {int n=5;float v[]={10,40,20,30,25};float w[]={15,12,8,9,10};float x[5];float c=21.5;knapsack(c,n,v,w,x);for(int i=0;i<n;i++){cout<<x[i]<<" ";}cout<<endl;return 0;
}int greedySelector(int s[],int f[],bool a[],int n){//n代表事件个数,bool类型的数组a表示活动i是否被安排//各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排序int i=0,j=0,count=0;//i表示处理的第i个活动,j表示刚刚安排的活动,count记录安排活动的数量//初始化a[i]=true;//安排第一个事件j=0;count++;for(i=1;i<n;i++){if(s[i]>f[j]) {a[i]=true;j = i;count++;}else{a[i]=false;}}return count;
}float knapsack(float c,int n,float v[],float w[],float x[]){//函数的返回值表示总价值//c表示背包容量//n表示物品个数//数组v表示价值value,数组w表示重量weight,数组x表示每个物品放入背包的比例struct node *p=new struct node[n];int i,j;float sum=0;for(i=0;i<n;i++){p[i].number=i;p[i].value=v[i];p[i].weight=w[i];x[i]=0;}quickSort(p,0,n-1);for(i=0;i<n;i++){if(p[i].weight>c){break;}else{x[p[i].number]=1;sum+=p[i].value;c-=p[i].weight;}}if(i<n){x[p[i].number]=c/p[i].weight;sum+=p[i].value*c/p[i].weight;}delete []p;return sum;
}int partition(struct node a[],int first,int end){int i=first,j=end;struct node temp;while(i<j){while(i<j&&(a[j].value/a[j].weight)<=(a[i].value/a[i].weight)){--j;}if(i<j){temp=a[i];a[i]=a[j];a[j]=temp;}while(i<j&&(a[j].value/a[j].weight)<=(a[i].value/a[i].weight)){++i;}if(i<j){temp=a[i];a[i]=a[j];a[j]=temp;}}return i;//i==j时,返回轴值
}void quickSort(struct node a[],int first,int end){if(first<end){int pos=partition(a,first,end);quickSort(a, first, pos-1);quickSort(a, pos+1, end);}
}

贪心算法不适用于0-1背包问题:

对于0-1背包问题,贪心算法得不到最优解。

无法保证最终能够将背包装满,部分闲置的背包空间使得单位重量的价值变低了。

在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再做出最好选择。由此导出了许多相互重叠的子问题,这正是利用动态规划求解的重要特征。

 

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

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

相关文章

百岁时代即将来临,原知因成为消费新潮流

什么叫长寿时代?泰康保险首席执行官陈东升指出&#xff1a;长寿时代&#xff0c;就是百岁人生即将来临&#xff0c;人人带病长期生存。而在这个时代&#xff0c;人类最大的变化在于“生命尺度的改变”&#xff0c;比如过去20岁是年轻人&#xff0c;40岁中年人&#xff0c;60岁…

哈工大《软件工程专业导论》复习指南

哈工大软件工程专业导论复习指南 文章目录 哈工大软件工程专业导论复习指南前言引言——软件工程专业导论课程引言第一章 软件工程专业初步认知第二章 软件体系结构与生命周期第三章 软件需求工程第四章 软件设计与实现第五章 软件质量与软件工程管理第六章 软件工程教育与职业…

经典综述|88.1分力作!土壤塑料际

柏林-勃兰登堡高级生物多样性研究所在《Nature reviews microbiology》期刊上(IF88.1)发表的“The soil plastisphere”研究论文中&#xff0c;综述了塑料对土壤的潜在影响。对土壤塑料际特性和微生物群落以及这些群落影响过程的阐明仍处于早期阶段&#xff0c;但进展的步伐很快…

提升测试工具开发的思考

本文针对测试部效率提升测试工具开发、管理、维护暴露出来的问题的一些思考以及一些个人改进观点。 写在前面 本文提到的效率提升测试工具不是指的部门中固有的自动化测试工具&#xff0c;这里提到的测试工具统一指测试人员在工作之余自主开发用于期望替代重复、繁琐、耗时的手…

Nature 确认:大语言模型只是没有感情的「学人精」

DeepMind、EleutherAI 科学家提出&#xff0c;大模型只是在角色扮演。 ChatGPT 爆火后&#xff0c;大语言模型一跃而至&#xff0c;成为了行业与资本的宠儿。而在人们或是猎奇、或是探究地一次次对话中&#xff0c;大语言模型所表现出的过度拟人化也引起了越来越多的关注。 其实…

【数据结构】哈希经典应用:布隆过滤器(哈希+位图)——[深度解析](9)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 数据结构 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴 数据结构 专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.布隆过滤器产生的…

第31期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Plasmocin® Treatment (ant-mpt)可用于干细胞支原体污染清除

Plasmocin™作为Invivogen的支原体抗生素产品之一&#xff0c;受国内外许多科研工作者使用并大力推广。其包含大环内酯物及对苯二酚两种主要成分&#xff0c;可有效作用于支原体复制的蛋白合成阶段和DNA复制阶段&#xff0c;只需两周即可清除支原体污染&#xff0c;并且不会影响…

【CANoe】CANoe手动发送XCP报文读取观测量

文章目录 1、硬件连接&#xff1a;配置CANoe的CAN端口&#xff0c;连接到ECU标定对应的CAN口2、配置CAN IG模块报文&#xff1a;连接XCP&#xff0c;读取观测量&#xff0c;断开XCP3、报文解析4、参考资料 1、硬件连接&#xff1a;配置CANoe的CAN端口&#xff0c;连接到ECU标定…

构筑安全之城:迅软DSE助力大型建筑企业打造数据防泄密方案

电子文件如今已成为各大建筑机构和设计院进行信息存储的主要方式&#xff0c;以及信息交换的重要载体。而对于如何保护好单位内的设计图纸、工程方案等重要资料的数据防泄密问题&#xff0c;就需要相关单位规划好一套合规有效的数据防泄密解决方案。 企业简介 该企业是我国最早…

压缩pdf怎么压缩又小又清晰?超级实用!

当PDF文件过大时&#xff0c;很容易遇到无法上传等现象&#xff0c;这时候我们可以借助一些专业的压缩工具&#xff0c;将PDF文件压缩变小&#xff0c;如果你还不知道怎么做&#xff0c;下面就来看下具体的压缩方法吧。 方法一&#xff1a;使用嗨格式压缩大师 1、打开电脑上安…

Leetcode 78 子集

题意理解&#xff1a; 求一个集合的所有子集。该集合中没有重复元素。 首先明确什么是子集&#xff1a;子集中的元素都在全集里。 [1,2,3] 子集&#xff1a;[]、[1]、[2]、[3]、[12]、[13]、[23]、[123] 注意&#xff1a;[]空集是所有集合的子集。 解题思路&#xff1a; 类似于…

【obs】官方最强插件obs-websocket入门

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ obs-websocket简介OBS版本说明obs-websocket版本说明安装&#xff08;27.x版本OBS&#xff09;配置插件 2️⃣ OBS-web介绍特征使用方法-5.xhttp vs https 3️⃣ obs-websocket-js开发tester.html 4️⃣ 其它开源项目obs-stud…

vue2-使用vue-i18n搭建多语言切换环境

安装 注意&#xff1a;vue2.0要用8版本的&#xff0c;使用9版本的会报错 npm install vue-i18n8.27.0 --save 创建相关的语言包文件 在src目录下&#xff0c;新建i18n文件夹 在新文件夹i18n中新建langs文件夹&#xff0c;里边放语言文本文件.js zh.js&#xff1a;存…

ADC学习总结

ADC的架构分类&#xff1a; 1、Delta-Sigma 采样率一般是在1M以内&#xff0c;位数一般可以做的很高&#xff0c;比如24位&#xff0c;Delta-Sigma ADC采用了过采样技术&#xff0c;不需要在模拟输入端加抗混叠滤波&#xff0c;由后端数字滤波器进行处理&#xff0c;通过信噪…

Yearning安装及使用

Yearning是基于go和vue开发的一款SQL审核工具。在实际开发中&#xff0c;生产环境DDL、DML脚本一般需要走工单流程进行审批后执行&#xff0c;Yearning可以制定MySQL的SQL审核流程、规范及审批等功能。 一、主要功能 1.支持自定义SQL审核流程2.自动化SQL语句审核,可对SQL进行…

初学者如何入门 Generative AI 之 Stable Diffusion 与 CLIP :看两篇综述,玩几个应用感受一下先!超多高清大图,沉浸式体验

文章大纲 4种 图片生成 的算法扩散模型的起源Stable DiffusionUNetCLIP参考文献与学习路径A synthography of an astronaut riding a horse created in NightCafe Studio with Stable Diffusion XL (SDXL). Prompt is a photograph of an astronaut riding a horse with weight…

MySQL之DML语句

DML语句 数据操作语言DML&#xff08;Data Manipulation Langua&#xff09; 是SQL语言的一个分类&#xff0c;用于对表的数据进行增&#xff0c;删&#xff0c;改&#xff0c;查 创建表 CREATE TABLE 语句用于创建数据库中的表。 语法&#xff1a; CREATE TABLE 表名称 (列…

DDD领域驱动架构设计学习网站和开源框架

文章目录 介绍1、国外Axon2、阿里Cola 介绍 近年来&#xff0c;关于DDD的讨论越来越多&#xff0c;关于网上的文章很多都是理论上的介绍&#xff0c;由于自己最近也在学习相关知识&#xff0c;所以分享几个关于DDD落地的开源框架。 1、国外Axon Axon是国外一款比较系统的DDD…

matlab信号分选系统算法-完整算法结构

matlab信号分选系统算法 针对得到的脉冲流PDW进行信号分选&#xff0c;包括重频恒定、重频抖动、重频参差和重频滑变四种脉间调制类型。   这里我们先进行数据的仿真&#xff0c;后续边仿真边分享思路&#xff1a;首先根据信号类型&#xff0c;分别产生重频恒定、重频抖动、重…