Python應用算法之貪心算法理解和實踐

一、什么是貪心算法?

貪心算法(Greedy Algorithm)是一種簡單而高效的算法設計思想,其核心思想是:在每一步選擇中,都采取當前狀態下最優的選擇(即“局部最優解”),希望通過一系列局部最優解最終達到全局最優解。雖然貪心算法并不總是能得到全局最優解,但在許多問題中,它能夠快速找到近似最優解。

1. 貪心算法的優缺點

優點

  • 高效性:通常時間復雜度較低,適合解決大規模問題。
  • 簡單性:實現簡單,易于理解和應用。
  • 實用性:在許多實際問題中(如調度、路徑規劃等),貪心算法能快速找到近似最優解。

缺點

  • 局限性:貪心算法并不總是能得到全局最優解。
  • 適用范圍有限:需要滿足貪心選擇性質和最優子結構性質。

2. 貪心算法的適用場景

貪心算法適用于滿足以下條件的問題:

  • 貪心選擇性質:可以通過局部最優選擇逐步構造全局最優解。
  • 最優子結構:問題的最優解可以通過子問題的最優解構造。
  • 如果不滿足上述條件,貪心算法可能無法得到正確結果。例如,在某些情況下,動態規劃可能是更好的選擇。

二、貪心算法經典問題與解法

1. 貪心算法的核心思想

貪心算法的特點可以總結為以下幾點:
(1)局部最優選擇
在每一步決策時,選擇當前看起來最優的選項。
不考慮未來的后果,也不回溯之前的決策。
(2)無后效性
一旦做出某個選擇,就不會再改變。
每一步的決策只依賴于當前狀態,而不依賴于之前的狀態。
(3)貪心選擇性質
全局最優解可以通過一系列局部最優選擇來構造。
(4)最優子結構性質
問題的最優解包含其子問題的最優解。

2. 經典貪心算法示例

2.1 活動選擇問題

問題描述:
給定一組活動,每個活動有開始時間和結束時間,要求選擇盡可能多的互不沖突的活動。
算法描述:
按活動的結束時間排序。
每次選擇最早結束的活動,并排除與之沖突的活動。
代碼實現:

def activity_selection(start, finish):# 按結束時間排序activities = sorted(zip(start, finish), key=lambda x: x[1])selected = []last_finish_time = -1for start_time, finish_time in activities:if start_time >= last_finish_time:  # 如果活動不沖突selected.append((start_time, finish_time))last_finish_time = finish_timereturn selected# 調用函數
start_times = [1, 3, 0, 5, 8, 5]
finish_times = [2, 4, 6, 7, 9, 9]
print("Selected activities:", activity_selection(start_times, finish_times))

2.2 分數背包問題(Fractional Knapsack Problem)

問題描述:
給定一組物品,每個物品有重量和價值,要求在不超過背包容量的情況下,最大化總價值。允許將物品分割。
算法描述:
計算每個物品的單位價值(價值/重量)。
按單位價值從高到低排序。
盡量裝入單位價值最高的物品,直到背包裝滿。
代碼實現:

def fractional_knapsack(weights, values, capacity):# 計算單位價值并排序items = sorted([(v / w, w, v) for v, w in zip(values, weights)],key=lambda x: x[0],reverse=True)total_value = 0for value_per_weight, weight, value in items:if capacity >= weight:total_value += valuecapacity -= weightelse:total_value += value_per_weight * capacitybreakreturn total_value# 調用函數
weights = [10, 20, 30]
values = [60, 100, 120]
capacity = 50
print("Maximum value:", fractional_knapsack(weights, values, capacity))

3. 貪心算法刷力扣題

3.1 無重疊區間(LeetCode原題435題)

問題描述
給定一個區間的集合 intervals,其中 intervals[i] = [start_i, end_i],返回需要移除的最小區間數量,使得剩余區間互不重疊。
解題思路:
按區間的結束時間排序。
每次選擇最早結束的區間,并移除與之重疊的區間。
代碼實現:

def eraseOverlapIntervals(intervals):if not intervals:return 0intervals.sort(key=lambda x: x[1])  # 按結束時間排序count = 0end = intervals[0][1]for i in range(1, len(intervals)):if intervals[i][0] < end:  # 當前區間與前一個區間重疊count += 1else:end = intervals[i][1]  # 更新結束時間return count
# 調用函數
intervals = [[1, 2], [2, 3], [3, 4], [1, 3]]
print(eraseOverlapIntervals(intervals))  
# 輸出: 1

3.2 跳躍游戲(LeetCode 原題55題)

問題描述:
給定一個非負整數數組 nums,你最初位于數組的第一個位置。數組中的每個元素代表你在該位置可以跳躍的最大長度。判斷你是否能夠到達最后一個位置。
解題思路:
維護一個變量 max_reach 表示當前能到達的最遠位置。
遍歷數組時,更新 max_reach,如果當前位置超過了 max_reach,則無法到達終點。
代碼實現:

def canJump(nums):max_reach = 0for i, jump in enumerate(nums):if i > max_reach:  # 當前位置不可達return Falsemax_reach = max(max_reach, i + jump)return max_reach >= len(nums) - 1# 調用函數
nums = [2, 3, 1, 1, 4]
print(canJump(nums))  
# 輸出: True

4. 優化方法

4.1 數據預處理

(1)排序
貪心算法通常依賴于某種順序(如活動的結束時間、物品的單位價值等),因此對數據進行適當的排序是關鍵。
使用高效的排序算法(如快速排序或歸并排序)可以減少預處理的時間開銷。
(2)去重或過濾
在某些情況下,可以通過去重或過濾無效數據來減少計算量。

4.2 使用優先隊列優化選擇過程

當需要動態選擇當前最優元素時,可以使用優先隊列(如最小堆或最大堆)來加速選擇過程。

4.3 并行化與分布式計算

對于獨立的子問題,可以使用多線程或多進程并行處理。

4.4 近似算法優化

(1)放松約束條件
在某些情況下,可以通過放松約束條件來簡化問題,從而使貪心算法更高效。
例如,在分數背包問題中,允許分割物品可以顯著簡化問題。
(2)局部搜索優化
在貪心算法的基礎上,可以通過局部搜索(如交換相鄰元素)進一步優化結果。
示例:任務調度問題
使用貪心算法生成初始調度方案后,通過交換任務順序來減少總完成時間。

三、總結

貪心算法,名思義,總是做出當前的最優選擇,即期望通過局部的最優選擇獲得整體的最優選擇。
某種意義上說,貪心算法是很貪婪、很目光短淺的,它不從整體考慮,僅僅只關注當前的最大利益,所以說它做出的選擇僅僅是某種意義上的局部最優,但是貪心算法在很多問題上還是能夠拿到最優解或較優解。

1. 注意事項

(1)適用條件:問題需滿足貪心選擇性質(局部最優可推導全局最優)和最優子結構。例如,分數背包滿足貪心性質,而0-1背包不滿足。
(2)驗證必要性:貪心策略的正確性需通過數學歸納法或反證法嚴格證明。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896029.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896029.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896029.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

競爭與冒險問題【數電速通】

時序邏輯電路&#xff1a; 組合邏輯電路中的競爭與冒險問題&#xff1a; 在組合邏輯電路中&#xff0c;競爭和冒險是兩種常見的時序問題&#xff0c;它們通常由電路的延時特性和不完美的設計引起。下面是這兩種現象的詳細解釋&#xff1a; 1. 競爭&#xff08;Race Condition&…

nasm - BasicWindow_64

文章目錄 nasm - BasicWindow_64概述筆記nasm_main.asmmy_build.batEND nasm - BasicWindow_64 概述 學個demo, 這個demo最主要學到了: 不用在調用每個API前都準備陰影區&#xff0c;在API調用后棧平衡。 可以在函數入口處考慮到所用的棧尺寸最大值(16字節對齊&#xff0c;陰…

JavaScript變量的作用域介紹

JavaScript變量的作用域介紹 JavaScript 變量的作用域決定了變量在代碼中的可訪問性。 var 是 JavaScript 中最早用于聲明變量的關鍵字&#xff0c;它函數作用域或全局作用域。 let 關鍵字&#xff0c;具有塊級作用域、全局作用域。 const關鍵字&#xff0c;具有塊級作用域…

Microsoft 365 Copilot中使用人數最多的是哪些應用

今天在瀏覽Microsoft 365 admin center時發現&#xff0c;copilot會自動整理過去30天內所有用戶使用copilot的概況&#xff1a; 直接把這個圖丟給copilot讓它去分析&#xff0c;結果如下&#xff1a; 總用戶情況 總用戶數在各應用中均為 561 人&#xff0c;說明此次統計的樣本…

ue5.2.1 quixel brideg顯示asset not available in uAsset format

我從未見過如此傻x的bug&#xff0c;在ue5.2.1上通過內置quixel下載資源顯示 asset not available in uAsset format 解決辦法&#xff1a;將ue更新到最新版本&#xff0c;通過fab進入商場選擇資源后add to my library 點擊view in launcher打開epic launcher&#xff0c;就可…

當電腦上有幾個python版本Vscode選擇特定版本python

查看當前vscode用的python版本命令 Import sys print(sys.version) 修改VSCODE解釋器 打開 VSCode。 按下 CtrlShiftP打開命令面板。 輸入 Python: Select Interpreter 并選擇它。 從彈出的列表中選擇你安裝的 Python 解釋器。如果你有多個 Python 版本&#xff08;例如…

Vue 中 nextTick 的原理詳解

1. 為什么需要 nextTick Vue 采用 異步渲染機制&#xff0c;當響應式數據發生變化時&#xff0c;Vue 并不會立即更新 DOM&#xff0c;而是將這些變化放入一個 隊列 中&#xff0c;并在 同一事件循環&#xff08;Event Loop&#xff09;中合并相同的修改&#xff0c;最后執行批…

Spring面試題2

1、compareable和compactor區別 定義與包位置:Comparable是一個接口&#xff0c;位于java.lang包,需要類去實現接口&#xff1b;而Compactor是一個外部比較器&#xff0c;位于java.util包 用法&#xff1a;Comparable只需要實現int compareTo(T o) 方法&#xff0c;比較當前對…

DuodooBMS源碼解讀之 cncw_statement模塊

財務應收應付擴展模組用戶使用手冊 一、模塊概述 財務應收應付擴展模組是一個基于 Odoo18 的擴展模塊&#xff0c;主要對財務應收應付相關功能進行了修改和增強。該模塊增加了多個功能模塊&#xff0c;如預收款單模塊、費用類別設置模塊等&#xff0c;同時對發票、公司、銷售…

JUC并發—9.并發安全集合四

大綱 1.并發安全的數組列表CopyOnWriteArrayList 2.并發安全的鏈表隊列ConcurrentLinkedQueue 3.并發編程中的阻塞隊列概述 4.JUC的各種阻塞隊列介紹 5.LinkedBlockingQueue的具體實現原理 6.基于兩個隊列實現的集群同步機制 4.JUC的各種阻塞隊列介紹 (1)基于數組的阻塞…

vue項目啟動時報錯:error:0308010C:digital envelope routines::unsupported

此錯誤與 Node.js 的加密模塊有關&#xff0c;特別是在使用 OpenSSL 3.0 及以上版本時。Vue 項目在啟動時可能會依賴一些舊的加密算法&#xff0c;而這些算法在 OpenSSL 3.0 中默認被禁用&#xff0c;導致 error:0308010C:digital envelope routines::unsupported 錯誤。 解決…

ncDLRES:一種基于動態LSTM和ResNet的非編碼RNA家族預測新方法

現有的計算方法主要分為兩類&#xff1a;第一類是通過學習序列或二級結構的特征來預測ncRNAs家族&#xff0c;另一類是通過同源序列之間的比對來預測ncRNAs家族。在第一類中&#xff0c;一些方法通過學習預測的二級結構特征來預測ncRNAs家族。二級結構預測的不準確性可能會導致…

愛普生 SG-8101CE 可編程晶振在筆記本電腦的應用

在筆記本電腦的精密架構中&#xff0c;每一個微小的元件都如同精密儀器中的齒輪&#xff0c;雖小卻對整體性能起著關鍵作用。如今的筆記本電腦早已不再局限于簡單的辦公用途&#xff0c;其功能愈發豐富多樣。從日常輕松的文字處理、網頁瀏覽&#xff0c;到專業領域中對圖形處理…

SPRING10_getBean源碼詳細解讀、流程圖

文章目錄 ①. getBean方法的入口-DefaultListableBeanFactory②. DefaultListableBeanFactory調用getBean③. 進入到doGetBean方法④. getSingleton三級緩存方法⑤. getSingleton()方法分析⑥. createBean創建對象方法⑦. 對象創建、屬性賦值、初始化⑧. getBean最詳細流程圖 ①…

IDEA中查詢Maven項目的依賴樹

在Maven項目中&#xff0c;查看項目的依賴樹是一個常見的需求&#xff0c;特別是當你需要了解項目中直接或間接依賴了哪些庫及其版本時。你可以通過命令行使用Maven的dependency:tree插件來做到這一點。這個命令會列出項目中所有依賴的樹狀結構。 打開idea項目的終端&#xff…

深入xtquant:財務數據獲取與應用的實戰指南

深入xtquant&#xff1a;財務數據獲取與應用的實戰指南 在量化交易領域&#xff0c;雖然技術分析和市場情緒分析占據了主導地位&#xff0c;但財務數據作為評估公司基本面的重要依據&#xff0c;同樣不可或缺。xtquant作為一個強大的Python庫&#xff0c;提供了便捷的接口來獲…

windows 安裝 stable diffusion

在windows上安裝 stable diffusion&#xff0c;如果windows沒有nvidia顯卡&#xff0c;想只使用CPU可在webui-user.bat中添加命令 set COMMANDLINE_ARGS--no-half --skip-torch-cuda-test 可正常使用stable diffusion&#xff0c;但速度較慢

Kubernetes控制平面組件:APIServer 基于 引導Token 的認證機制

云原生學習路線導航頁&#xff08;持續更新中&#xff09; kubernetes學習系列快捷鏈接 Kubernetes架構原則和對象設計&#xff08;一&#xff09;Kubernetes架構原則和對象設計&#xff08;二&#xff09;Kubernetes架構原則和對象設計&#xff08;三&#xff09;Kubernetes控…

DeepSeek 助力 Vue 開發:打造絲滑的縮略圖列表(Thumbnail List)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

DeepSeek寫俄羅斯方塊手機小游戲

DeepSeek寫俄羅斯方塊手機小游戲 提問 根據提的要求&#xff0c;讓DeepSeek整理的需求&#xff0c;進行提問&#xff0c;內容如下&#xff1a; 請生成一個包含以下功能的可運行移動端俄羅斯方塊H5文件&#xff1a; 核心功能要求 原生JavaScript實現&#xff0c;適配手機屏幕 …