主頁 >  其他 > 【技識訓累】演算法中的貪心演算法【二】

【技識訓累】演算法中的貪心演算法【二】

2023-06-10 07:59:59 其他

如何證明一個問題可以使用貪心演算法解決?

判斷一個問題是否可以使用貪心演算法解決,通常需要滿足兩個條件:

  1. 貪心選擇性質:問題的最優解可以通過一系列區域最優解得到,也就是說,在每一步選擇中,都選擇當前最優解,而不考慮之后的影響,
  2. 最優子結構性質:問題的子問題的最優解可以推匯出原問題的最優解,也就是說,問題的子問題的最優解可以重復利用,從而得到原問題的最優解,

因此,如果一個問題滿足以上兩個條件,就可以使用貪心演算法解決,但是,需要注意的是,貪心演算法得到的解不一定是全域最優解,而是區域最優解,因此,在使用貪心演算法時,需要根據具體問題來判斷是否能夠得到全域最優解,

貪心演算法的時間和空間復雜度是什么?

貪心演算法的時間復雜度通常是O(n log n)或O(n),其中n是問題的規模,

空間復雜度通常是O(1),因為貪心演算法通常只需要存盤一些變數來跟蹤最優解,

以下是一個例子,展示如何使用貪心演算法解決集合覆寫問題:

假設有一個需要覆寫的集合,以及一些可用于覆寫集合的子集,我們的目標是找到最少的子集,以便覆寫整個集合,

set_cover(sets, universe):
  # Initialize the empty list of selected sets
  selected_sets = []
  # Create a copy of the universe to track remaining elements
  remaining_elements = set(universe)
  # Continue until all elements are covered
  while remaining_elements:
    # Select the set that covers the most remaining elements
    best_set = max(sets, key=lambda s: len(s & remaining_elements))
    # Add the selected set to the list of selected sets
    selected_sets.append(best_set)
    # Update the remaining elements to exclude those covered by the selected set
    remaining_elements -= best_set
  return selected_sets

在這個例子中,時間復雜度為O(n log n),其中n是集合的大小,空間復雜度為O(n),因為我們需要存盤所有的子集和剩余元素,

使用貪心演算法時有哪些常見陷阱? 

使用貪心演算法時,常見的陷阱有以下幾點:

  1. 區域最優解不一定是全域最優解:貪心演算法通常只考慮當前步驟的最優解,而不是全域最優解,因此,如果貪心演算法選擇的區域最優解無法達到全域最優解,那么結果就會出現錯誤,
  2. 無法回溯:貪心演算法做出的選擇通常是不可逆的,因此一旦做出了錯誤的選擇,就無法回溯到之前的狀態進行修正,
  3. 需要正確性證明:雖然貪心演算法通常很簡單,但是在某些情況下,它可能會給出錯誤的結果,因此需要進行正確性證明,

以下是一個貪心演算法的案例,用來說明常見的陷阱: 假設有一個背包,可以裝載重量為W的物品,現在有n個物品,每個物品有一個重量w和一個價值v,我們的目標是選擇一些物品,使得它們的總重量不超過W,并且它們的總價值最大,

偽代碼如下:

GreedyKnapsack(W, w[], v[], n):
    // W為背包容量,w[]為物品重量,v[]為物品價值,n為物品數量
    totalValue = https://www.cnblogs.com/yyyyfly1/p/0
    for i = 1 to n:
        if w[i] <= W:
            // 選擇當前物品
            totalValue += v[i]
            W -= w[i]
        else:
            // 當前物品無法裝入背包
            totalValue += (v[i] / w[i]) * W
            break
    return totalValue

如何證明貪心演算法的最優性?

要證明貪心演算法的最優性,通常需要使用數學歸納法或反證法,下面是一個簡單的例子,展示如何使用數學歸納法證明貪心演算法的最優性:

問題:假設你有n個任務,每個任務有一個開始時間和結束時間,你想要找到一種方法,使你能夠完成盡可能多的任務,而不會出現時間沖突,

貪心演算法:按照任務的結束時間對任務進行排序,然后從第一個任務開始,依次選擇結束時間最早的任務,直到所有任務都完成,

證明:我們使用數學歸納法證明貪心演算法的最優性,

基本情況:當n=1時,貪心演算法顯然是最優的,

歸納假設:假設當n=k時,貪心演算法是最優的,

歸納步驟:

  1. 考慮n=k+1的情況,
  2. 我們將任務按照結束時間排序,然后依次選擇結束時間最早的任務,
  3. 假設我們選擇了任務i作為第一個任務,那么我們需要找到剩余任務中結束時間最早的任務j,
  4. 由于任務i結束時間最早,所以任務j的開始時間一定晚于任務i的結束時間,
  5. 我們可以將任務j從剩余任務中洗掉,然后繼續在剩余任務中選擇結束時間最早的任務,
  6. 由于我們已經洗掉了一個任務,所以剩余任務的數量為k,
  7. 根據歸納假設,我們知道貪心演算法在k個任務上是最優的,因此,我們可以使用貪心演算法來完成這k個任務,而不會出現時間沖突,
  8. 由于任務i和任務j沒有時間沖突,所以我們可以將它們一起完成,
  9. 因此,貪心演算法也是在n=k+1個任務上是最優的,
  10. 因此,根據數學歸納法,我們證明了貪心演算法的最優性,

下面是一個使用偽代碼實作的例子:

Sort tasks by their end times
selected_tasks = []
last_end_time = 0
for task in tasks:
    if task.start_time >= last_end_time:
        selected_tasks.append(task)
        last_end_time = task.end_time
return selected_tasks


在這個例子中,我們首先將任務按照結束時間進行排序,然后,我們從第一個任務開始,依次選擇結束時間最早的任務,如果我們選擇的任務的開始時間晚于上一個任務的結束時間,那么我們將該任務添加到已選擇的任務串列中,并將其結束時間設定為last_end_time,最后,我們回傳已選擇的任務串列,

貪心演算法和動態規劃演算法有什么區別?

貪心演算法和動態規劃演算法的區別在于它們解決問題的方式和適用范圍不同,

貪心演算法通常使用貪心選擇性質和最優子結構性質來解決問題,每一步都選擇當前最優解,并且不回溯之前的選擇,因此,貪心演算法的時間復雜度通常較低,但是它無法保證得到全域最優解,因為它只考慮了當前步驟的最優解,而沒有考慮之后步驟的影響,貪心演算法適用于一些特定型別的問題,如最小生成樹、最短路徑、背包問題等,

動態規劃演算法則是一種將問題分解成子問題并重復利用已經計算出的結果的方法,它通常需要使用記憶化搜索或者自底向上的迭代方法來求解問題,動態規劃演算法的時間復雜度通常比貪心演算法高,但是它能夠保證得到全域最優解,動態規劃演算法適用于那些具有最優子結構性質和重疊子問題的問題,如背包問題、最長公共子序列、最長遞增子序列等,

在效率方面,貪心演算法通常更高效,因為它只需要考慮當前步驟的最優解,而不需要回溯之前的選擇,因此,貪心演算法的時間復雜度通常較低,適用于一些特定型別的問題,如最小生成樹、最短路徑、背包問題等,

在準確性方面,貪心演算法得到的解不一定是全域最優解,而是區域最優解,因此,在某些情況下,貪心演算法無法保證得到全域最優解,動態規劃演算法可以保證得到全域最優解,

因此,在選擇演算法時,需要根據具體問題的特點來選擇合適的演算法,以達到最優的效果,

貪心演算法求解最小頂點覆寫問題

給定一個無向圖G=(V,E),尋找最小的頂點集合S,使得對于每一條邊(u,v)∈E,至少有一個端點屬于S,

  1. 初始化頂點集合S為空集,
  2. 對于每條邊(u,v)∈E,如果u和v都沒有被覆寫,則將u和v中任意一個頂點加入集合S中,
  3. 重復步驟2,直到所有的邊都至少有一個端點被覆寫,
  4. 回傳集合S,
VertexCover(G):
    S = empty set
    for each edge (u, v) in E:
        if u is not in S and v is not in S:
            add any vertex from {u, v} to S
    return S

貪心演算法求解最小路徑覆寫問題?

給定一個有向無環圖G=(V,E),尋找最小的路徑集合P,使得每個頂點恰好出現在一條路徑中,

  1. 將有向無環圖G轉化為一個二分圖G'=(V',E'),其中V'={u,v|u,v∈V},對于每個頂點v∈V,將其拆分為兩個頂點u,v',其中u表示頂點v作為起點的路徑,v'表示頂點v作為終點的路徑,
  2. 在二分圖G'上運行最大匹配演算法,得到最大匹配M,
  3. 對于每個未匹配的頂點u∈V,將其作為起點的路徑加入路徑集合P中,
  4. 對于每個匹配的邊(u,v')∈M,將路徑u->v'加入路徑集合P中,
  5. 回傳路徑集合P,
MinimumPathCover(G):
    G' = transform G into a bipartite graph
    M = find maximum matching in G'
    P = empty set
    for each vertex u in V:
        if u is not matched in M:
            add path u to P
    for each edge (u, v') in M:
        add path u->v' to P
    return P

貪心演算法求解最大子矩陣問題?

給定一個n行m列的矩陣A,矩陣中的元素為整數,尋找一個子矩陣B,使得B中所有元素之和最大,

  1. 對于每一行i∈[1,n],計算以第i行為底部的矩陣中每列的元素之和,得到一個長度為m的一維陣列sum,
  2. 對于每一對行i,j∈[1,n],計算以第i行和第j行為底部的矩陣中每列的元素之和,得到一個長度為m的一維陣列diff,其中diff[k]=sum[k]-A[i][k]-A[j][k],
  3. 對于陣列diff,使用最大子序列和演算法求解最大子矩陣的列范圍,設最大子矩陣的列范圍為[l,r],
  4. 對于每一行i∈[1,n],計算以第i行為底部,列范圍為[l,r]的矩陣中所有元素之和,取所有結果中的最大值,
  5. 回傳最大子矩陣的元素之和,
MaximumSubmatrix(A):
    n, m = dimensions of A
    max_sum = -infinity
    for i from 1 to n:
        sum = array of length m, initialized to 0
        for j from i to n:
            for k from 1 to m:
                sum[k] += A[j][k]
            diff = array of length m-1, initialized to 0
            for k from 1 to m-1:
                diff[k] = sum[k+1] - sum[k] - A[i][k] - A[j][k]
            [l, r] = find maximum subarray of diff
            row_sum = 0
            for k from l to r:
                row_sum += sum[k] - A[i][k] - A[j][k]
            max_sum = max(max_sum, row_sum)
    return max_sum

 

在黑夜里夢想著光,心中覆寫悲傷,在悲傷里忍受孤獨,空守一絲溫暖, 我的淚水是無底深海,對你的愛已無言,相信無盡的力量,那是真愛永在, 我的信仰是無底深海,澎湃著心中火焰,燃燒無盡的力量,那是忠誠永在,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/554773.html

標籤:其他

上一篇:DosBox環境配置

下一篇:返回列表

標籤雲
其他(160691) Python(38219) JavaScript(25489) Java(18216) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7241) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4589) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2435) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) 功能(1967) HtmlCss(1956) Web開發(1951) C++(1933) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1880) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 【技識訓累】演算法中的貪心演算法【二】

    博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ......

    uj5u.com 2023-06-10 07:59:59 more
  • DosBox環境配置

    # DosBox環境配置 DOSBox 是一個基于 x86 架構的 PC 的模擬器,它允許用戶在現代作業系統上運行 DOS 程式。DOSBox 是自由軟體,可以在 Windows、Linux ,macOS 等作業系統平臺上運行。 DOSBox 最初的設計目標是為那些依賴 MS-DOS 作業系統(即停 ......

    uj5u.com 2023-06-10 07:59:38 more
  • 網路傳輸中的重要引數-談談帶寬

    [toc] 除了上篇提到的[RTT與丟包率](https://www.cnblogs.com/mapleumr/p/17464980.html),大多數人更關心的也許是網路的帶寬(Bandwidth,Bw),畢竟電信、聯通等公司廣告主打的就是一個百兆、千兆帶寬,聽著嘎嘎猛。 很自然的一個認知是,帶寬 ......

    uj5u.com 2023-06-10 07:59:33 more
  • 幫您了解CDN節點如何做到訪問加速與安全防護

    本文分享自天翼云開發者社區《幫您了解CDN節點如何做到訪問加速與安全防護》,作者:尹****荷 網站業務痛點 在當前網站快速發展的背景下,網站業務突增往往伴隨著一系列網路安全隱患。主要會有以下痛點: 1. 高并發壓力大:網站在業務突增中,會帶來高并發的問題,可能會導致服務器資源耗盡、服務崩潰等引起的 ......

    uj5u.com 2023-06-10 07:59:23 more
  • 【計算機網路】延遲

    目錄 延遲 光速限制 總結 延遲 延遲是指資料從一個地方到另一個地方所需的時間。延遲通常用毫秒(ms)或微秒(μs)來度量。延遲是指資料從發送方到接收方所需的時間,也稱為往返時間(RTT)。 延遲取決于多個因素,包括網路拓撲結構、距離、中間節點數、傳輸介質和網路流量。在處理實時應用程式時,延遲是一個 ......

    uj5u.com 2023-06-10 07:59:16 more
  • 實體講解Flink 流處理程式編程模型

    摘要:在深入了解 Flink 實時資料處理程式的開發之前,先通過一個簡單示例來了解使用 Flink 的 DataStream API 構建有狀態流應用程式的程序。 本文分享自華為云社區《Flink 實體:Flink 流處理程式編程模型》,作者:TiAmoZhang 。 在深入了解 Flink 實時數 ......

    uj5u.com 2023-06-10 07:58:19 more
  • 虛擬ECU實踐:汽車發動機控制器仿真

    ?虛擬化技術使得在Windows PC上對汽車ECU(Electronic Control Unit,電子控制器單元)進行倍訓仿真成為可能,能有效改善ECU開發程序。一些開發任務得以從道路、測驗平臺和HIL(Hardware in the Loop,硬體在環)轉移到PC上,縮短開發時間和成本。 ▲汽 ......

    uj5u.com 2023-06-10 07:57:42 more
  • selenium-wire簡介

    一.簡介 以下來自chatGPT回答: selenium-wire是一個基于selenium的Python庫,它擴展了selenium的功能,使得我們可以在自動化測驗中直接訪問和修改瀏覽器的網路請求和回應。selenium-wire可以攔截和修改HTTP請求和回應,從而可以在測驗程序中模擬 網路環境 ......

    uj5u.com 2023-06-10 07:57:33 more
  • 9.3 Django框架

    Django 是一個非常流行的 Python Web 開發框架,它是完整且強大的,適用于構建大型 Web 應用。在這一章節中,我們將詳細介紹 Django 的基本概念、組件和用法。為了便于理解,我們將使用實體來展示如何使用 Django 構建一個簡單的 Web 應用。 ### 9.3.1 安裝和創建 ......

    uj5u.com 2023-06-10 07:57:18 more
  • RTOS測驗(韓國方案)

    ### 簡介 在本文中,我們重點討論了實時作業系統的驗證和測驗程式。 測驗的目的有兩個。一個是顯示經過驗證的模型屬性是否被繼承到了代碼中。另一個目的是發現代碼的錯誤要檢查結構覆寫率和功能等。 在測驗所開發的作業系統軟體后,我們將其與數字工廠保護系統(DPPS Digital Plant Protec ......

    uj5u.com 2023-06-09 08:02:10 more