c++矩阵连乘的动态规划算法并输出_「Javascript算法设计」× 动态规划与回溯算法...
目錄:
- 分而治之算法
- 動態規劃
- 回溯算法
分而治之算法
分而治之算法是算法設計的一種方式,它將一個問題分成多個和原問題相似的小問題,遞歸解決小問題,再將解決方式合并以解決原來的問題(例如快速排序,二分搜索等)
分而治之算法可以分成三個部分
我們利用二分搜索作為例子來看看什么是分而治之,利用分而治之的理念,實現二分搜索可以是以下邏輯:
首先,找到找不到搜索值時的終止條件(行{1}),也就是當左右邊界相觸時,表示找不到該值,返回 -1。然后定義中間值mid(行{2}),判斷中間值和搜索值的大小,若相等,直接返回中間值(行{3}),若中間值小于搜索值,這對左邊子數組進行搜索,將右邊邊界縮小到當前中間值的前一位(行{5}),進行下一輪遞歸,若中間值大于搜索值,則對右邊子數組進行搜索,將左邊邊界增加到當前中間值后一位(行{7}),進行下一輪遍歷。
注意,第一次傳入的函數的數組必須是經過排序的,并且low表示數組第一個下標,high表示數組最后一個下標
動態規劃
動態規劃(dynamic programming,DP)是一種將復雜問題分解成更小的子問題來解決的優化技術
注意:動態規劃和分而治之是不同的方法。分而治之方法是把問題分解成相互獨立的子問題,然后組合它們的答案,而動態規劃則是將問題分解成相互依賴的子問題。用動態規劃解決問題時,要遵循三個重要步驟:
下面我們通過兩個例子來看動態規劃的實戰操作(背包問題,最長公共子序列)
· 背包問題
背包問題是一個組合優化問題,它可以描述如下:
給定一個固定大小,能夠攜重量W的背包,以及以組有價值和重要的物品,找出一個最佳解決方案,使得裝入背包的物品總重量不超過W,且總價值最大
例子:
考慮背包能夠攜帶的重要只有5,我們規定只能往背包里裝完整的物品(0-1背包)。對于這個例子,我們可以說最佳解決方案是往背包里裝入物品1和物品2,這樣總重要5,總價值為7
我們來實現這個背包算法:
function我們來分析上面這段代碼是如何工作的
搜先,初始化將用于尋找解決方案的矩陣(行{1})。矩陣為 kS[n+1][capacity + 1]。然后,忽略矩陣的第一列和第一行,只處理索引不為0的列和行(行{2})并且要迭代數組中每個可用的項。物品i的重要必須小于約束capacity(行{3})才有可能成為解決方案的一部分;否則,總重要就會超出背包能夠攜帶的重要,這是不可能發生的。發生這種情況時,只要忽略它,用之前的值就可以了(行{5})。當找到可以構成解決方案的物品時,選擇價值最大的那個(行{4})。然后,問題的解決方案就在這個二維表格右下角的最后一個格子里(行{7})
我們做一個測試用例
const values = [3,4,5] weights = [2,3,4] capacity = 5 n = values.length下圖說明例子中kS矩陣的構造
請注意,這個算法只輸出背包攜帶物品價值的最大值,而不列出實際的物品。我們可以增加下面的附加函數找出構成解決方案的物品(行{6})
function· 最長公共子序列
另一個經常被當作編程挑戰問題的動態規劃問題是最長公共子序列(LCS):找出兩個字符串序列的最長子序列的長度。最長子序列是指,在兩個字符串序列中以相同順序出現,但不要求連續(非字符串子串)的字符串序列
考慮如下的例子。
再看看具體的算法
function與背包問題比較,我們會發現兩者非常相似,這項從頂部開始構建解決方案的技術被稱為記憶化,而解決方案就在表格或矩陣的右下角
我們用圖來展示:
回溯算法
回溯是一種漸進式尋找并構建問題解決方式的策略。我們從一個可能的動作開始并試著用這個動作解決問題。如果不能解決,就回溯并選擇另一個動作直到將問題解決。根據這種行為,回溯算法會嘗試所有可能的動作(如果更快找到了解決方法就嘗試較少的次數)來解決問題
我們以迷宮老鼠問題來看回溯算法
假設我們有一個大小為N x N的矩陣,矩陣的每個位置是一個方塊。每個位置(或塊)可以是空閑的(值為1)或是被阻擋的(值為0),如下圖所示,其中S是起點,D是終點
矩陣就是迷宮,‘老鼠’的目標是從位置[0][0]開始并移動到[n-1][n-1](終點)。老鼠可以在垂直或水平方向上任何未被阻擋的位置間移動
我們先聲明下算法的基本結構
function首先創建一個包含解的矩陣。將每個位置初始化為零(行{1})。對于老鼠采取的每步行為,我們將路徑標記為1。如果算法能夠找到一個解(行{2}),就返回解決矩陣,否則返回一條錯誤信息(行{3})
然后我們開始構思findPath函數,它會試著從位置x和y開始在給定的maze矩陣中找到一個解。回溯技巧也使用遞歸,這也是這個算法有回溯能力的原因
function算法的第一步是驗證老鼠是否到達了終點(行{4}),如果到了,就將最后一個位置標記為路徑的一部分并且返回true,表示移動成功結束。如果不是最后一步,要驗證老鼠能否安全移動至該位置(行{5} 表示根據下面聲明的isSafe方法判斷出該位置空閑)。如果是安全的,我們將這步加入路徑(行{6})并試著在maze矩陣中水平移動(向右)到下一個位置(行{7})。如果水平移動不可行,我們就試著垂直向下移動到下一個位置(行{8})。如果水平和垂直都不能移動,那么將這步從路徑中移除并回溯(行{9}),表示算法會嘗試另一個可能的解。在算法嘗試了所有可能的動作之后還是找不到解時,就返回false(行{10}),表示這個問題無解
實現isSafe函數
function下面進行測試
const maze = [[1,0,0,0],[1,1,1,1],[0,0,1,0],[0,1,1,1] ] console.log(ratInAMaze(maze))總結
以上是生活随笔為你收集整理的c++矩阵连乘的动态规划算法并输出_「Javascript算法设计」× 动态规划与回溯算法...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AirPods Pro怎么连接设备Air
- 下一篇: c++ 反射_固体火箭发动机黏接壳体超声