常見的演算法設計策略

来源:https://www.cnblogs.com/superXIAOZHI/archive/2019/05/10/10844826.html
-Advertisement-
Play Games

常見的演算法設計策略 1.分治 分治法的設計思想是,將一個難以直接解決的大問題,分割成k個規模較小的子問題,這些子問題相互獨立,且與原問題相同,然後各個擊破,分而治之。 分治法常常與遞歸結合使用:通過反覆應用分治,可以使子問題與原問題類型一致而規模不斷縮小,最終使子問題縮小到很容易求出其解,由此自然導 ...


 常見的演算法設計策略

1.分治

      分治法的設計思想是,將一個難以直接解決的大問題,分割成k個規模較小的子問題,這些子問題相互獨立,且與原問題相同,然後各個擊破,分而治之。

      分治法常常與遞歸結合使用:通過反覆應用分治,可以使子問題與原問題類型一致而規模不斷縮小,最終使子問題縮小到很容易求出其解,由此自然導致遞歸演算法。

      根據分治法的分割原則,應把原問題分割成多少個子問題才比較適宜?每個子問題是否規模相同或怎樣才為適當?這些問題很難給與肯定的回答。但人們從大量實踐中發現,在使用分治法時,最好均勻劃分,且在很多問題中可以取k=2。這種使子問題規模大致相等的做法源自一種平衡子問題的思想,它幾乎總是比使子問題規模不等的做法好。

 

2.動態規劃

      動態規劃法與分治法類似,其基本思想也是將原問題分解成若幹個子問題。與分治法不同的是,其分解出的子問題往往不是相互獨立的。這種情況下若用分治法會對一些子問題進行多次求解,這顯然是不必要的。動態規劃法在求解過程中把所有已解決的子問題的答案保存起來,從而避免對子問題重覆求解。

      動態規劃常用於解決最優化問題。對一個最優化問題可否應用動態規劃法,取決於該問題是否具有如下兩個性質:

      1.最優子結構性質

      當問題的最優解包含其子問題的最優解時,稱該問題具有最優子結構性質。

      要證明原問題具有最優子結構性質,通常採用反證法。假設由問題的最優解導出的子問題的解不是最優的,然後再設法說明在該假設下可構造出比原問題的最優解更好的解,從而導致矛盾。

      2.子問題重疊性質

      子問題重疊性質是指由原問題分解出的子問題不是相互獨立的,存在重疊現象。

 

      用動態規劃法解題過程中,應當先找出最優解的結構特征,即原問題的最優解與其子問題的最優解的關聯。然後有如下兩種程式設計方法:

       1.自底向上遞歸法

       利用問題的最優子結構性質,以自底向上的方式遞歸地從子問題的最優解逐步構造出整個問題的最優解。

       2.自頂向下遞歸法(即備忘錄法)

       利用問題的最優子結構性質,用與直接遞歸法相同的控制結構自頂向下地進行遞歸求解。初始時在表格中為每個子問題存入一個標識解。在求解過程中,對每個待求子問題,首先查看表格中相應的記錄項。若記錄項為初始時的標識值,則表示該子問題是初次遇到,此時應利用問題的最優子結構性質進行遞歸求解,並將結果存入表格,以備以後查看。否則則說明該問題已被求解過,直接返回表格中相應的值即可,不必重新計算。

      當一個問題的所有子問題都要求解時,應當用自底向上遞歸法。當子問題空間中的部分子問題可不必求解時,自底向上遞歸法會進行多餘的計算,此時應採用自頂向下遞歸法。

 

3.貪心

      當一個問題具有最優子結構性質時,可用動態規劃法求解。但有時會有比動態規劃更簡單更直接效率更高的演算法——貪心法。貪心法總是做出在當前看來最好的選擇,也就是說貪心法並不從整體最優考慮,它所做出的選擇只是在某種意義上的局部最優選擇。雖然貪心法並不能對所有問題都得到整體最優解,但是對許多問題它能產生整體最優解。有些情況下,貪心法雖然不能得到整體最優解,但其最終結果卻是最優解的很好的近似。

      貪心法常用於解決最優化問題。對一個最優化問題可否應用貪心法,取決於該問題是否具有如下兩個性質:

      1.貪心選擇性質

      貪心選擇性質是指原問題總有一個整體最優解可通過當前的局部最優選擇,即貪心選擇來達到。

      對於一個具體問題,要確定它是否具有貪心選擇性質,通常可考察問題的一個整體最優解,並證明可修改這個最優解,使其以貪心選擇開始。由此證明該問題總有一個最優解可通過貪心選擇得到,即具有貪心選擇性質。

     2. 最優子結構性質

      這一點與動態規劃相同。做出貪心選擇後,由於最優子結構性質,原問題簡化為規模更小的類似子問題。如果將子問題的最優解和之前所做的貪心選擇合併,則可得到原問題的一個最優解。

 

      貪心問題的整體最優解可通過一系列局部的最優選擇,即貪心選擇來達到。這也是貪心法與動態規劃的主要區別。在動態規劃中,每一步所做出的選擇往往依賴於相關子問題的解。因而只有在解出相關子問題後,才能做出選擇。而在貪心法中,僅做出當前狀態下的最好選擇,即局部最優選擇。然後再去解做出這個選擇之後產生的相應的子問題。貪心法所做出的貪心選擇可以依賴於以往所做過的選擇,但絕不依賴於將來所做的選擇,也不依賴於子問題的解。正是由於這種差別,動態規劃通常以自頂向上的方式解各子問題,而貪心法通常以自頂向下的方式進行,以迭代的方式做出相繼的貪心選擇,每做出一次貪心選擇就將所求問題簡化為規模更小的子問題。

     

4.回溯

      回溯法是對問題的解空間樹進行深度優先搜索 ,但是在對每個節點進行DFS之前,要先判斷該節點是否有可能包含問題的解。如果肯定不包含,則跳過對以該節點為根的子樹的搜索,逐層向其祖先節點回溯。如果有可能包含,則進入該子樹,進行DFS。  

      回溯法通常的解題步驟如下:

     (1)定義問題的解空間。

     (2)將解空間組織成便於進行DFS的結構,通常採用樹或圖的形式。

     (3)對解空間進行DFS,併在搜索過程中用剪枝函數避免無效搜索。

      用回溯法解題時並不需要顯式地存儲整個解空間,而是在DFS過程中動態地產生問題的解空間。在任何時刻,演算法只保存從根節點到當前節點的路徑。如果解空間樹的高度為h,則回溯法的空間複雜度通常為O(h) 

      用回溯法解題時,常會遇到以下兩類典型的解空間樹:

      (1)當所給的問題是從n個元素的集合S中找出S滿足某種性質的子集時,相應的解空間樹稱為子集樹,例如http://www.cnblogs.com/laifeiyao/p/3481800.html

      (2)當所給的問題是找出n個元素滿足某種性質的排列時,相應的解空間樹稱為排列樹,例如http://www.cnblogs.com/laifeiyao/p/3492758.html

      回溯法中的剪枝函數通常分為兩類:

      (1)用約束函數在指定節點處剪去不滿足約束的子樹,例如http://www.cnblogs.com/laifeiyao/p/3481800.html

      (2)用限界函數在指定節點處剪去得不到最優解的子樹,例如http://www.cnblogs.com/laifeiyao/p/3492758.html

 

5.分支限界      

      回溯法是對解空間進行深度優先搜索,事實上任何搜索遍整個解空間的演算法均可解決問題。所以採用通用圖搜索(樹可抽象為特殊的圖)的任何實現作為搜索策略均可解決問題,只要做到窮舉即可。除了深度優先搜索之外,我們還可採用廣度優先搜索,而分支限界法則是對解空間進行優先順序優先搜索。

      分支限界法的搜索策略是,在當前節點處,先生成其所有的子節點(分支),併為每個滿足約束條件的子節點計算一個函數值(限界),再將滿足約束條件的子節點全部加入解空間樹的活結點優先隊列。然後再從當前的活節點優先隊列中選擇優先順序最大的節點(節點的優先順序由其限界函數的值來確定) 作為新的當前節點。重覆這一過程,直到到達一個葉節點為止。所到達的葉節點就是最優解。                                                                                                                                                                                                                                      

  分類: 演算法 標簽: 動態規劃回溯分支限界演算法設計分治
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 以下麵試題出自自己去各個公司面試遇到的,不乏各個大廠: 瀑布流 vuex幾個常用屬性 vue通過哪個js原聲方法實現數據監聽的 圖片截取上傳 懶載入和預載入 防抖動截流 flex幾個屬性背一下 手機端app優化 手機端調用相機webview 微信小程式 公眾號 js原生實現懶載入 Vue裡面,只要t ...
  • 小編整理javascript用的是有道雲筆記,導出的word版本,但是代碼塊顯示格式是亂的,不便於閱讀 所以,各位有需要的話,小編可以將導出的pdf版發給大家!pdf版跟word沒有什麼區別,知識沒法編輯而已! JavaScript 第一章 js介紹 js是和html混合使用的一種腳本語言,其編寫的 ...
  • 1 2 3 function fn(e) { 4 //---^--以什麼開頭----- 5 //---¥--以什麼結尾---- 6 //----{n}--連續有n個前面的檢測----- 7 var preg = /^1[3456789][0-9]{9}$/ ... ...
  • 已經學過無數次,但是每次都忘記,畢竟腦容量太小了,每次都需要翻看原來項目和視頻再次學習,所以以此文字形式記錄下來,方便於下次使用觀看 1、打開git,找到創建vue的文件夾(已經安裝好git的,然後在存儲項目的文件夾下滑鼠右鍵,有個git bash here) 2、命令 vue init webpa ...
  • 後臺方法的參數必須是@RequestBody修飾的。 前臺關鍵代碼: ...
  • [註]: popstate 事件 a.當活動歷史記錄條目更改時,將觸發popstate事件。 b.如果被激活的歷史記錄條目是通過對history.pushState()的調用創建的,或者受到對history.replaceState()的調用的影響,popstate事件的state屬性包含歷史條目的 ...
  • classdef SingletonClass < handle methods(Access = private) function obj = SingletonClass() disp('SingletonClass construtor called!'); end end methods(... ...
  • 電腦程式中涉及到的概念都比較抽象、專業。經常有初學者程式的人反應說,“別人說的什麼名詞性的東西,根本不明白是什麼意思”。的確,掌握一些開發相關的概念,與別人溝通起來非常的方便。對於初學者經常問的問題,做了個總結,希望給大家帶來幫助。 Q:經常聽到有人說,電腦語言可以歸為面向過程語言和麵向對象語言 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...