【贪心算法】原理思想、算法步骤,应用示例(找零问题、活动选择问、霍夫曼编码、最小生成树问题、车辆路径问题)

        贪心算法是一种基于贪心策略的优化算法,它在每一步选择中都采取当前状态下的最优决策,而不考虑未来的后果。通常,这种算法对于解决一些最优化问题非常有效,尤其是那些可以通过局部最优解来达到全局最优解的问题。

1 贪心算法的基本思想:

  1. 建立贪心选择的标准: 在每一步选择中,根据某个标准选择当前最优的解。
  2. 做出选择: 基于建立的标准,做出当前最优的选择。
  3. 更新问题: 通常,做出选择后,问题将被更新为一个子问题。解决子问题,继续应用贪心策略。

2 示例:找零问题

问题描述: 给定一些面额不同的硬币,如1元、5元、10元,要找零n元,找零的硬币数量要尽可能少。

贪心策略: 在每一步选择中,选择面额最大的硬币,直到找零的总金额达到n。

算法步骤:

  1. 初始化一个空列表,用于存储找零的硬币。
  2. 从面额最大的硬币开始,将尽可能多的这个硬币加入列表,直到总金额超过n。
  3. 如果总金额等于n,算法结束。否则,将面额减小到次大的硬币,重复步骤2。

Python 代码示例:

def greedy_change(n, coins):coins.sort(reverse=True)  # 按面额降序排列change = []  # 存储找零的硬币total = 0  # 当前找零的总金额for coin in coins:while total + coin <= n:change.append(coin)total += coinreturn change# 示例
n = 63
coin_denominations = [1, 5, 10, 20, 50]
result = greedy_change(n, coin_denominations)
print("Greedy Change for", n, ":", result)

在这个例子中,贪心算法首先选择面额最大的硬币(50元),然后选择10元,最后选择3个1元,完成找零过程。尽管这个算法可能无法得到最优解,但它通常能够得到一个近似最优解,而且计算效率高。

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

  • 问题描述: 给定一系列活动,每个活动都有开始时间和结束时间,目标是选择尽可能多的互不相交的活动。
  • 贪心策略: 在每一步选择中,选择结束时间最早的活动,以便腾出更多时间给其他活动。
  • 应用场景: 会议室安排、课程表安排等。
  • Python 代码示例:
  • def activity_selection(activities):# 按照结束时间排序sorted_activities = sorted(activities, key=lambda x: x[1])selected_activities = [sorted_activities[0]]  # 选择第一个活动last_end_time = sorted_activities[0][1]# 选择互不相交的活动for activity in sorted_activities[1:]:if activity[0] >= last_end_time:selected_activities.append(activity)last_end_time = activity[1]return selected_activities# 示例
    activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
    result = activity_selection(activities)
    print("Selected Activities:", result)
    

    在这个示例中,我们首先将活动按照结束时间进行排序,然后从第一个活动开始,依次选择结束时间不与已选择活动相交的活动,直到无法选择更多活动为止。

4 示例:霍夫曼编码(Huffman Coding):

  • 问题描述: 给定一组字符及其出现的频率,构建一个最优的二进制编码,使得出现频率高的字符具有较短的编码。
  • 贪心策略: 构建霍夫曼树,选择出现频率最低的两个节点合并,重复此过程直到只剩一个节点。
  • 应用场景: 数据压缩、图像编码等。
  • Python 代码示例:
  • import heapq
    from collections import defaultdict# 定义霍夫曼树的节点类
    class HuffmanNode:def __init__(self, char, freq):self.char = charself.freq = freqself.left = Noneself.right = Nonedef __lt__(self, other):return self.freq < other.freq# 构建霍夫曼树
    def build_huffman_tree(freq_map):# 利用最小堆来实现构建霍夫曼树的过程min_heap = [HuffmanNode(char, freq) for char, freq in freq_map.items()]heapq.heapify(min_heap)while len(min_heap) > 1:left = heapq.heappop(min_heap)right = heapq.heappop(min_heap)merged = HuffmanNode(None, left.freq + right.freq)merged.left = leftmerged.right = rightheapq.heappush(min_heap, merged)return min_heap[0]# 生成霍夫曼编码
    def generate_huffman_codes(root, current_code, codes):if root is not None:if root.char is not None:codes[root.char] = current_codegenerate_huffman_codes(root.left, current_code + '0', codes)generate_huffman_codes(root.right, current_code + '1', codes)# 霍夫曼编码
    def huffman_coding(text):freq_map = defaultdict(int)for char in text:freq_map[char] += 1root = build_huffman_tree(freq_map)codes = {}generate_huffman_codes(root, '', codes)# 将原始文本编码为霍夫曼编码encoded_text = ''.join(codes[char] for char in text)return encoded_text, codes# 示例
    text_to_encode = "huffman coding is fun!"
    encoded_text, huffman_codes = huffman_coding(text_to_encode)# 打印结果
    print("Original Text:", text_to_encode)
    print("Encoded Text:", encoded_text)
    print("Huffman Codes:", huffman_codes)
    

    这段代码演示了如何使用贪心算法构建霍夫曼树,并生成字符的霍夫曼编码。在实际应用中,霍夫曼编码通常用于数据压缩,以便更有效地存储和传输数据。

    在这个示例中,我们首先统计了给定文本中每个字符的出现频率,并构建了一个霍夫曼树。然后,通过遍历霍夫曼树,生成每个字符的二进制编码。最终,我们将原始文本编码为霍夫曼编码。霍夫曼编码通常用于数据压缩,通过给出出现频率高的字符较短的编码来减小数据的存储空间。

5  示例:最小生成树问题(Minimum Spanning Tree):

  • 问题描述: 给定一个连通的无向图,找到一个最小权重的树,使得图中所有节点都连接在一起。
  • 贪心策略: 使用Kruskal算法或Prim算法,每次选择边权重最小的边加入生成树。
  • 应用场景: 网络设计、电缆布线等。
  • Python 代码示例:
    • import heapqdef prim(graph):n = len(graph)visited = [False] * nmin_heap = [(0, 0)]  # (权重, 节点)的最小堆minimum_spanning_tree = []while min_heap:weight, node = heapq.heappop(min_heap)if not visited[node]:visited[node] = Trueminimum_spanning_tree.append((weight, node))for neighbor, edge_weight in graph[node]:heapq.heappush(min_heap, (edge_weight, neighbor))return minimum_spanning_tree# 示例
      graph = {0: [(1, 2), (3, 1)],1: [(0, 2), (3, 3), (2, 1)],2: [(1, 1), (3, 5)],3: [(0, 1), (1, 3), (2, 5)]
      }result = prim(graph)
      print("Minimum Spanning Tree:", result)
      

      在这个示例中,我们使用Prim算法构建了一个最小生成树。算法从起始节点开始,选择与当前生成树连接的边中权重最小的边,然后将连接的节点加入生成树。这一过程重复直到所有节点都加入生成树为止。

6 示例:车辆路径问题(Vehicle Routing Problem):

  • 问题描述: 有一组客户点和一个中心仓库,目标是找到一条路径,使得所有客户都被访问,并且路径总长度最短。
  • 贪心策略: 从仓库出发,选择离当前位置最近的客户点,重复此过程直到所有客户都被访问。
  • 应用场景: 物流配送、快递路线规划等。
  • Python 代码示例:
  • import numpy as npdef euclidean_distance(point1, point2):# 计算两点之间的欧几里德距离return np.linalg.norm(np.array(point1) - np.array(point2))def vehicle_routing(customers, warehouse):route = [warehouse]  # 路线的起始点是仓库remaining_customers = set(customers)while remaining_customers:# 计算当前位置到所有剩余客户点的距离,并选择最近的客户点current_location = route[-1]nearest_customer = min(remaining_customers, key=lambda customer: euclidean_distance(current_location, customer))# 将最近的客户点添加到路线中route.append(nearest_customer)remaining_customers.remove(nearest_customer)# 返回最终路线return route# 示例
    warehouse_location = (0, 0)
    customer_locations = [(1, 2), (3, 5), (6, 8), (9, 4), (7, 1)]final_route = vehicle_routing(customer_locations, warehouse_location)# 打印结果
    print("Warehouse Location:", warehouse_location)
    print("Customer Locations:", customer_locations)
    print("Final Route:", final_route)
    

    这段代码演示了如何使用贪心算法解决车辆路径问题。在这个问题中,我们有一组客户点和一个中心仓库,目标是找到一条路径,使得所有客户都被访问,并且路径总长度最短。通过选择每次最近的客户点进行访问,贪心算法可以得到一个近似最优解。在实际应用中,车辆路径问题常常出现在物流配送和快递路线规划等场景中。

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

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

相关文章

pg_bouncer在使用中的坑勿踩

目录 简介 环境信息 问题配置 问题配置 启动pgbouncer 链接逻辑图 测试存在问题 pgadmin4 Idea JAVA调用 ​编辑 dbeaver 建议&#xff1a; 简介 前面文章说过关于pg_bouncer的安装讲解&#xff0c;这里讲一下在使用中的坑&#xff0c;在进行配置的时候需要注意。 …

系列三、双亲委派机制

一、概述 当一个类收到了类加载的请求&#xff0c;它首先不会尝试自己去加载这个类&#xff0c;而是把这个请求委派给父类去完成&#xff0c;每一层的类加载器都是如此&#xff0c;因此所有的请求都应该传送到启动类加载器中&#xff0c;只有当父类加载器反馈自己无法完成这个…

PowerPoint技巧:如何将一张图片同时加到全部幻灯片里?

想把一张图片加到PPT每一张幻灯片的同一个位置&#xff0c;如果一张一张的添加就太耗时间了&#xff0c;一起来看看如何利用母版快速设置同时添加吧。 首先&#xff0c;打开需要编辑的PPT&#xff0c;在菜单栏依次点击【视图】→【幻灯片母版】&#xff1b; 打开母版后&#x…

vue3实现数据大屏内数据向上滚动,鼠标进入停止滚动 vue3+Vue3SeamlessScroll

1.效果图 2.npm下载依赖及main.js文件配置 npm install vue3-seamless-scroll --saveimport vue3SeamlessScroll from vue3-seamless-scroll;app.use(vue3SeamlessScroll) 3.html代码 <!-- scrollFlag为true时再渲染,vue3只要涉及到传值子页面需要加flag判断&#xff0c;否…

【BIM入门实战】Revit图元的选择方式,总有一款适合你

Revit图元的五种常见选择方式,总有一款适合你。 文章目录 一、直接单击二、加选和减选三、连续框选四、按类别选择五、全选过滤选择操作可以在三维视图、平面视图等多种视图中进行。 一、直接单击 直接单击,即可选中某一个图元,如选择一个扶手。 二、加选和减选 按住ctrl键…

python 调用HEG对MODIS数据进行批处理

HEG其实可以批处理可以看我另外一篇博文&#xff0c;不需要写代码。但是对于300以上数量的MODIS影像非常容易自动停止&#xff0c;而且越来越慢。还是打算利用python每个调用。 只提取了MODIS数据当中的IST一个波段&#xff0c;输出成tif&#xff0c;其他什么都没做。在处理前…

yum提示Another app is currently holding the yum lock; waiting for it to exit...

解决方法&#xff1a; rm -f /var/run/yum.pid 再重新运行yum 原因&#xff1a;可能是系统自动升级正在运行&#xff0c;yum在锁定状态中&#xff0c;要等待那个进程结束退出: 另一个应用程序是&#xff1a;PackageKit内存&#xff1a; 29 M RSS &#xff08;445 MB VSZ&…

vue-router配置

1、路由安装 npm install vue-router4 2、创建router目录 3、编辑文件且引入router包 4、main.js引入

Ubuntu18.04平台下Qt开发程序打包的一些问题总结

目录 前言 一、在Ubuntu18.04开发环境下打包有两种方式 1、利用linuxdeployqt软件进行打包 2、利用编写shell脚本的方式进行打包 二、详细介绍shell脚本打包的方式 1、新建一个空的文件夹 2、准备脚本copylib.sh 3、准备脚本xxxx.sh。 4、给上述两个脚本添加可执行权限…

Git目录不对,即当前文件夹不对应git仓库

报错信息是&#xff1a; fatal: not a git repository (or any of the parent directories): .git 如&#xff1a; 是当前文件夹不对应git仓库&#xff0c;一般在git clone之后&#xff0c;需要进入下一级文件夹才对应仓库。 在文件夹看&#xff0c;本层中没有.git文件夹&…

JavaScript的函数的形参与实参是怎么回事

0 写在前面 此文给小白看的&#xff0c;如果不是可以直接关闭 1 讲解 例如JavaScript中定义函数 //定义函数 function 方法名(形参){方法体-->使用形参}//使用函数 方法名字(实参)具体干了什么呢&#xff1f;此处以伪代码举例 //定义函数 function eat(A,B){A 去 B 家吃…

C_9练习题

一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) C语言程序中,要使用数学库函数(例sqrt、sin等),需要在程序最前面加上包含文件的预处理命令&#xff08;)。 A. #include <…

解决STM32F429烧录程序后还需复位才能植入程序的bug

1.打开魔术棒&#xff0c;打开debug 2.打开setting 3.打开Flas Download 4.开启Reset and Run 5.点进去Pack选项页面&#xff0c;去掉enable

部署LCM(Latent Consistency Models)实现快速出图

LCM&#xff08;Latent Consistency Models&#xff09;可以通过很少的迭代次数就可以生成高清晰度的图片&#xff0c;目前只可以使用一个模型Dreamshaper_v7&#xff0c;基于SD版本Dreamshaper微调而来的。 LCM模型下载&#xff1a; https://huggingface.co/SimianLuo/LCM_D…

wpr -start generalprofile -start pool -filemode 这句命令具体是什么意思

注意事项&#xff1a; 总体而言&#xff0c;WPR 和 WPA 是强大的性能分析工具&#xff0c;通过它们&#xff0c;你可以深入了解系统运行时的性能特性&#xff0c;找出潜在问题并进行优化。 查看详细信息&#xff1a; wpr -start generalprofile -start pool -filemode 对应的结…

内存泄漏、new、delete

1. 内存泄漏 内存泄漏&#xff1a;指针被销毁&#xff0c;指针指向的空间依旧存在 2. new过程 与内存分配、构造函数有关 1&#xff09;分配空间&#xff1a;void* mem operator new( sizeof( ) )&#xff0c;内部调用malloc 2&#xff09;static_cast<目标类型>(mem) …

快速删除MySQL服务 。

以管理员身份执行终端&#xff0c;输入&#xff1a;sc delete MYSQL&#xff08;这个名字按着自己的来&#xff0c;可能是MYSQL8或者MYSQL5.7&#xff0c;有些时还不需要名字是一样的话&#xff0c;你要看服务名字是什么&#xff09;&#xff0c;就可以把服务中的MYSQL删除了 …

centos 6.10 安装 svn1.14.2

安装 apr 和 apr-util 下载地址 我下载的分别是 apr-1.7.4 和 apr-unit-1.6.3 常规的安装步骤 ./configure --prefix/usr/local/xxx make && make install注意要先安装 apr 再安装 apr-unit-1.6.3 安装 lz4 下载地址 要配置好环境变量&#xff0c;不然可能还是找…

.Net(C#)常用转换byte转uint32、byte转float等

1、byte转String Encoding.ASCII.GetString(byte[]); 2、base64string转byte byte[]Base64Decoder.Decoder.GetDecoded(string); 3、byte转UInt16 方法一 (UInt16)(bytes[0] * 256 bytes[1]) 方法二 (UInt16)((bytes[0] << 8) | bytes[1]); 方法三 字节序要对…

记feign调用第三方接口时header是multipart/form-data

1.请求第三方接口&#xff0c;用feign请求 请求第三方接口&#xff0c;用feign请求&#xff0c;header不通&#xff0c;feign的写法不同 调用时报错Could not write request: no suitable HttpMessageConverter found for request type [com.ccreate.cnpc.mall.dto.zm.ZMPage…