亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

動態規劃原理及其實現

2019-11-14 12:43:38
字體:
來源:轉載
供稿:網友

原理入門理論最優化原理問題求解模式實現思路狀態實現最長公共子序列湊硬幣

原理

入門理論

最優化原理

1951年美國數學家R.Bellman等人,根據一類多階段問題的特點,把多階段決策問題變換為一系列互相聯系的單階段問題,然后逐個加以解決。一些靜態模型,只要人為地引進“時間”因素,分成時段,就可以轉化成多階段的動態模型,用動態規劃方法去處理。與此同時,他提出了解決這類問題的“最優化原理”(PRinciple of optimality):

“一個過程的最優決策具有這樣的性質:即無論其初始狀態和初始決策如何,其今后諸策略對以第一個決策所形成的狀態作為初始狀態的過程而言,必須構成最優策略”。簡言之,一個最優策略的子策略,對于它的初態和終態而言也必是最優的。

這個“最優化原理”如果用數學化一點的語言來描述的話,就是:假設為了解決某一優化問題,需要依次作出n個決策D1,D2,…,Dn,如若這個決策序列是最優的,對于任何一個整數k,1 < k < n,不論前面k個決策是怎樣的,以后的最優決策只取決于由前面決策所確定的當前狀態,即以后的決策Dk+1,Dk+2,…,Dn也是最優的。

最優化原理是動態規劃的基礎。任何一個問題,如果失去了這個最優化原理的支持,就不可能用動態規劃方法計算。能采用動態規劃求解的問題都需要滿足一定的條件: (1) 問題中的狀態必須滿足最優化原理; (2) 問題中的狀態必須滿足無后效性。 所謂的無后效性是指:“下一時刻的狀態只與當前狀態有關,而和當前狀態之前的狀態無關,當前的狀態是對以往決策的總結”。(這個感覺和馬爾科夫模型很像) (3) 子問題的重疊性 動態規劃將原來具有指數級時間復雜度的搜索算法改進成了具有多項式時間復雜度的算法。其中的關鍵在于解決冗余,這是動態規劃算法的根本目的。動態規劃實質上是一種以空間換時間的技術,它在實現的過程中,不得不存儲產生過程中的各種狀態,所以它的空間復雜度要大于其它的算法。

問題求解模式

動態規劃所處理的問題是一個多階段決策問題,一般由初始狀態開始,通過對中間階段決策的選擇,達到結束狀態。這些決策形成了一個決策序列,同時確定了完成整個過程的一條活動路線(通常是求最優的活動路線)。如圖所示。動態規劃的設計都有著一定的模式,一般要經歷以下幾個步驟。

      初始狀態→│決策1│→│決策2│→…→│決策n│→結束狀態       動態規劃決策過程示意圖      

劃分階段:按照問題的時間或空間特征,把問題分為若干個階段。在劃分階段時,注意劃分后的階段一定要是有序的或者是可排序的,否則問題就無法求解。確定狀態和狀態變量:將問題發展到各個階段時所處于的各種客觀情況用不同的狀態表示出來。當然,狀態的選擇要滿足無后效性。確定決策并寫出狀態轉移方程:因為決策和狀態轉移有著天然的聯系,狀態轉移就是根據上一階段的狀態和決策來導出本階段的狀態。所以如果確定了決策,狀態轉移方程也就可寫出。但事實上常常是反過來做,根據相鄰兩段各狀態之間的關系來確定決策。尋找邊界條件:給出的狀態轉移方程是一個遞推式,需要一個遞推的終止條件或邊界條件。

實現思路

動態規劃的主要難點在于理論上的設計,也就是上面4個步驟的確定,一旦設計完成,實現部分就會非常簡單。使用動態規劃求解問題,最重要的就是確定動態規劃三要素:問題的階段,每個階段的狀態以及從前一個階段轉化到后一個階段之間的遞推關系。遞推關系必須是從次小的問題開始到較大的問題之間的轉化,從這個角度來說,動態規劃往往可以用遞歸程序來實現,不過因為遞推可以充分利用前面保存的子問題的解來減少重復計算,所以對于大規模問題來說,有遞歸不可比擬的優勢,這也是動態規劃算法的核心之處。確定了動態規劃的這三要素,整個求解過程就可以用一個最優決策表來描述,最優決策表是一個二維表,其中行表示決策的階段,列表示問題狀態,表格需要填寫的數據一般對應此問題的在某個階段某個狀態下的最優值(如最短路徑,最長公共子序列,最大價值等),填表的過程就是根據遞推關系,從1行1列開始,以行或者列優先的順序,依次填寫表格,最后根據整個表格的數據通過簡單的取舍或者運算求得問題的最優解。

動態規劃算法通?;谝粋€遞推公式及一個或多個初始狀態。 當前子問題的解將由上一次子問題的解推出。使用動態規劃來解題只需要多項式時間復雜度, 因此它比回溯法、暴力法等要快許多?,F在讓我們通過一個例子來了解一下DP的基本原理。首先,我們要找到某個狀態的最優解,然后在它的幫助下,找到下一個狀態的最優解。

最重要的就是確定動態規劃三要素: (1)問題的階段 (2)每個階段的狀態 (3)從前一個階段轉化到后一個階段之間的遞推關系。

遞推關系必須是從次小的問題開始到較大的問題之間的轉化,從這個角度來說,動態規劃往往可以用遞歸程序來實現,不過因為遞推可以充分利用前面保存的子問題的解來減少重復計算,所以對于大規模問題來說,有遞歸不可比擬的優勢,這也是動態規劃算法的核心之處。

確定了動態規劃的這三要素,整個求解過程就可以用一個最優決策表來描述,最優決策表是一個二維表,其中行表示決策的階段,列表示問題狀態,表格需要填寫的數據一般對應此問題的在某個階段某個狀態下的最優值(如最短路徑,最長公共子序列,最大價值等),填表的過程就是根據遞推關系,從1行1列開始,以行或者列優先的順序,依次填寫表格,最后根據整個表格的數據通過簡單的取舍或者運算求得問題的最優解。 f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}

舉個例子:

for(j=1; j<=m; j=j+1) // 第一個階段 xn[j] = 初始值; for(i=n-1; i>=1; i=i-1)// 其他n-1個階段 for(j=1; j>=f(i); j=j+1)//f(i)與i有關的表達式 xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])};t = g(x1[j1:j2]); // 由子問題的最優解求解整個問題的最優解的方案print(x1[j1]);for(i=2; i<=n-1; i=i+1){ t = t-xi-1[ji]; for(j=1; j>=f(i); j=j+1) if(t=xi[ji]) break;}

http://www.49028c.com/steven_oyj/archive/2010/05/22/1741374.html

實現思路有: 1.自頂向下(又稱記憶化搜索、備忘錄):基本上對應著遞歸函數實現,從大范圍開始計算,要注意不斷保存中間結果,避免重復計算; 2.自底向上(遞推):從小范圍遞推計算到大范圍; 動態規劃的重點:遞歸方程+邊界條件

動態規劃算法可以求解很多問題,比如矩陣乘法、最長公共子序列、構造最優二叉查找樹等,現就著名的最長公共子序列問題,采用動態規劃法分析之。

狀態

“狀態”用來描述該問題的子問題的解。

實現

最長公共子序列

子序列:若給定序列X={x1,x2,…,xm},則另一序列Z={z1,z2,…,zk},是X的子序列是指存在一個嚴格遞增下標序列{i1,i2,…,ik}使得對于所有j=1,2,…,k有:zj=xij.

公共子序列:給定2個序列X和Y,當另一序列Z既是X的子序列又是Y的子序列時,稱Z是序列X和Y的公共子序列.

最長公共子序列:給定2個序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最長公共子序列.

如:序列ABCDEF和ADFGH的最長公共子序列為ADF

注意:最長公共子串(Longest Common Substirng)和最長公共子序列(Longest Common Subsequence,簡稱LCS)的區別為是最長公共子串的串是一個連續的部分,而最長公共子序列則是從不改變序列的順序,而從序列中去掉任意的元素而獲得新的序列;通俗的說就是子串中字符的位置必須是連續的而子序列則可以不必連續。

問題描述:給定2個序列X={A,B,C,B,D,A,B}和Y={B,D,C,A,B,A},找出X和Y的最長公共子序列

1.分析最優子結構性質:

設序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最長公共子序列為Z={z1,z2,…,zk} ,則

(1)若xm=yn,則zk=xm=yn,且z1,z2,…, zk-1是否為x1,x2,…,xm-1和y1,y2,…,yn-1的最長公共子序列.

(2)若xm≠yn且zk≠xm,則Z是x1,x2,…,xm-1和Y的最長公共子序列.

(3)若xm≠yn且zk≠yn,則Z是X和y1,y2,…,yn-1的最長公共子序列.

由此可見,2個序列的最長公共子序列包含了這2個序列的前綴的最長公共子序列.因此,最長公共子序列問題具有最優子結構性質.當問題具有最優子結構性質和子問題重疊性質時就可以用動態規劃算法解決該問題.

2.由最長公共子序列問題的最優子結構性質建立子問題最優值的遞歸關系.用c[i][j]記錄序列和的最長公共子序列的長度.其中,Xi={x1,x2,…,xi},Yj={y1,y2,…,yj}.當i=0或j=0時,空序列是Xi和Yj的最長公共子序列.故此時C[i][j]=0.其它情況下,由最優子結構性質可建立遞歸關系如下: c[i][j]=?????0,c[i?1][j?1]+1,maxc[i?1][j],c[i][j?1],if i=0,j=0if x>0,y>0, xi>yjif i>0,j>0,xi≠yj  這里寫圖片描述

//LCS 最長公共子序列 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 void LCS(char *x, char *y,int x_len, int y_len, int common_len[][MAX], int b[][MAX]) { //common_len[i][j]存儲的是x的第i位與有的第j位的公共子序列的長度 //b[i][j] 記錄獲得common_len[i][j]的路徑:分別為0 -1 1,便于回溯輸出公共子串 int i,j; for (i = 0; i < x_len; i++) common_len[i][0] = 0; for (j = 0; j < y_len; j++) common_len[0][j] =0; for (i = 1; i <= x_len; i++) { for (j = 1; j <= y_len; j++) { if (x[i-1] == y[j-1]) //從零開始存儲,所以第i位為x[i-1] { common_len[i][j] = common_len[i-1][j-1] + 1; b[i][j] = 0; } else if (common_len[i-1][j] >= common_len[i][j-1]) { common_len[i][j] = common_len[i-1][j]; b[i][j] = -1; } else { common_len[i][j] = common_len[i][j-1]; b[i][j] = 1; } } } } void backtrack(int i, int j,int b[][MAX], char *x) { if (0 == i || 0 == j) return; else if (0 == b[i][j]) { backtrack(i-1,j-1,b,x); printf("%c",x[i-1]); } else if(-1 == b[i][j]) { backtrack(i-1,j,b,x); } else { backtrack(i,j-1,b,x); } } int main() { int x_len,y_len; char x[MAX] = "ABCBDAB"; char y[MAX] = "BDCABA"; int common_len[MAX][MAX]; int b[MAX][MAX]; x_len = strlen(x); y_len = strlen(y); LCS(x,y,x_len,y_len,common_len,b); backtrack(x_len,y_len,b,x); printf("/n"); return 0; }

http://www.2cto.com/kf/201611/565606.html http://m.codes51.com/article/detail_556679.html

湊硬幣

如果我們有面值為1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠11元? (表面上這道題可以用貪心算法,但貪心算法無法保證可以求出解,比如1元換成2元的時候)

首先我們思考一個問題,如何用最少的硬幣湊夠i元(i<11)?為什么要這么問呢? 兩個原因:1.當我們遇到一個大問題時,總是習慣把問題的規模變小,這樣便于分析討論。 2.這個規模變小后的問題和原來的問題是同質的,除了規模變小,其它的都是一樣的, 本質上它還是同一個問題(規模變小后的問題其實是原問題的子問題)。

好了,讓我們從最小的i開始吧。當i=0,即我們需要多少個硬幣來湊夠0元。 由于1,3,5都大于0,即沒有比0小的幣值,因此湊夠0元我們最少需要0個硬幣。 (這個分析很傻是不是?別著急,這個思路有利于我們理清動態規劃究竟在做些什么。) 這時候我們發現用一個標記來表示這句“湊夠0元我們最少需要0個硬幣。”會比較方便, 如果一直用純文字來表述,不出一會兒你就會覺得很繞了。那么, 我們用d(i)=j來表示湊夠i元最少需要j個硬幣。于是我們已經得到了d(0)=0, 表示湊夠0元最小需要0個硬幣。當i=1時,只有面值為1元的硬幣可用, 因此我們拿起一個面值為1的硬幣,接下來只需要湊夠0元即可,而這個是已經知道答案的, 即d(0)=0。所以,d(1)=d(1-1)+1=d(0)+1=0+1=1。當i=2時, 仍然只有面值為1的硬幣可用,于是我拿起一個面值為1的硬幣, 接下來我只需要再湊夠2-1=1元即可(記得要用最小的硬幣數量),而這個答案也已經知道了。 所以d(2)=d(2-1)+1=d(1)+1=1+1=2。一直到這里,你都可能會覺得,好無聊, 感覺像做小學生的題目似的。因為我們一直都只能操作面值為1的硬幣! 讓我們看看i=3時的情況。當i=3時,我們能用的硬幣就有兩種了:1元的和3元的( 5元的仍然沒用,因為你需要湊的數目是3元!5元太多了親)。 既然能用的硬幣有兩種,我就有兩種方案。如果我拿了一個1元的硬幣,我的目標就變為了: 湊夠3-1=2元需要的最少硬幣數量。即d(3)=d(3-1)+1=d(2)+1=2+1=3。 這個方案說的是,我拿3個1元的硬幣;第二種方案是我拿起一個3元的硬幣, 我的目標就變成:湊夠3-3=0元需要的最少硬幣數量。即d(3)=d(3-3)+1=d(0)+1=0+1=1. 這個方案說的是,我拿1個3元的硬幣。好了,這兩種方案哪種更優呢? 記得我們可是要用最少的硬幣數量來湊夠3元的。所以, 選擇d(3)=1,怎么來的呢?具體是這樣得到的:d(3)=min{d(3-1)+1, d(3-3)+1}。 我們要抽出動態規劃里非常重要的兩個概念:狀態和狀態轉移方程。

上文中d(i)表示湊夠i元需要的最少硬幣數量,我們將它定義為該問題的”狀態”, 這個狀態是怎么找出來的呢?我在另一篇文章 動態規劃之背包問題(一)中寫過: 根據子問題定義狀態。你找到子問題,狀態也就浮出水面了。 最終我們要求解的問題,可以用這個狀態來表示:d(11),即湊夠11元最少需要多少個硬幣。 那狀態轉移方程是什么呢?既然我們用d(i)表示狀態,那么狀態轉移方程自然包含d(i), 上文中包含狀態d(i)的方程是:d(3)=min{d(3-1)+1, d(3-3)+1}。沒錯, 它就是狀態轉移方程,描述狀態之間是如何轉移的。當然,我們要對它抽象一下,

d(i)=min{ d(i-vj)+1 },其中i-vj >=0,vj表示第j個硬幣的面值。

偽代碼為: 這里寫圖片描述

參考鏈接:

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=dynProg http://www.hawstein.com/posts/dp-novice-to-advanced.html http://dev.21tx.com/2007/01/17/11010.html

動態規劃與貪婪算法的區別:

http://www.programgo.com/article/67512173783/ http://amp.itgo.me/a/3219840973004004279

動態規劃的教程算法以及源碼

http://www.xuebuyuan.com/zt/4352330.html https://www.codechef.com/wiki/tutorial-dynamic-programming


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品旅馆在线| 国产精品偷伦一区二区| 中文字幕亚洲激情| 国产精品日韩一区| x99av成人免费| 午夜精品久久久久久久久久久久久| 九九久久国产精品| 国内精品视频一区| 中文字幕在线看视频国产欧美在线看完整| 欧美国产日韩免费| 久久免费视频这里只有精品| 国产玖玖精品视频| 亚洲成色777777在线观看影院| 久久久噜噜噜久久久| 97香蕉久久夜色精品国产| 精品亚洲一区二区三区在线播放| 欧美日韩激情美女| 136fldh精品导航福利| 国产亚洲一区精品| 国内精品视频在线| 久久久久久久久国产精品| 国产成人激情视频| 91精品中国老女人| 久久99久国产精品黄毛片入口| 亚洲影院色在线观看免费| 富二代精品短视频| 国产精品狼人色视频一区| 久久人人97超碰精品888| 国产精品午夜国产小视频| 免费91麻豆精品国产自产在线观看| 久久久久久久香蕉网| 亚洲精品一区二区在线| 精品国产乱码久久久久久婷婷| 日韩精品视频在线播放| 亚洲韩国欧洲国产日产av| 日韩电影中文字幕在线| 性欧美激情精品| 大荫蒂欧美视频另类xxxx| 在线亚洲欧美视频| 国产日本欧美一区二区三区在线| 91免费视频国产| 久久久精品国产亚洲| 在线视频日韩精品| 欧美床上激情在线观看| 高清日韩电视剧大全免费播放在线观看| 91久久精品日日躁夜夜躁国产| 国产日韩欧美在线视频观看| 国产精品丝袜视频| 亚洲欧美中文日韩v在线观看| 日韩国产欧美区| 精品久久久国产精品999| 日韩精品免费在线观看| 另类视频在线观看| 欧美成人激情视频免费观看| 欧美激情综合亚洲一二区| 欧美激情第三页| 欧美另类在线播放| 亚洲91精品在线观看| 欧美日韩一区二区三区在线免费观看| 91精品视频观看| 日韩三级成人av网| 国产伦精品免费视频| 日韩精品免费综合视频在线播放| 亚洲国产精品小视频| 国产亚洲激情视频在线| 91九色综合久久| 国语自产精品视频在线看抢先版图片| 在线播放亚洲激情| 国产成人精品电影| 亚洲电影av在线| 在线播放国产一区中文字幕剧情欧美| 久久资源免费视频| 欧美一区二区大胆人体摄影专业网站| 国产精品露脸自拍| 欧美亚洲第一页| 欧美又大粗又爽又黄大片视频| 色樱桃影院亚洲精品影院| 国产精品视频白浆免费视频| 91免费视频国产| 国产一区二区香蕉| 国产精品男女猛烈高潮激情| 96精品视频在线| 久久99视频免费| 欧美成人精品在线视频| 亚洲美女免费精品视频在线观看| 97久久精品人搡人人玩| 久久精品国产69国产精品亚洲| 九九久久久久久久久激情| 91视频免费在线| 色综合导航网站| 亚洲欧美日韩直播| 96国产粉嫩美女| 国产91久久婷婷一区二区| 欧美激情一级欧美精品| 久久亚洲国产精品成人av秋霞| 欧美日韩一区二区三区| 亚洲精品久久在线| 国产成人中文字幕| 欧美精品中文字幕一区| 国产精品扒开腿做爽爽爽的视频| 欧美一级bbbbb性bbbb喷潮片| 日韩欧美成人区| 欧美电影在线观看| 91精品久久久久久久久久久久久久| 中文字幕视频在线免费欧美日韩综合在线看| 国内精品久久久久影院 日本资源| 欧美大学生性色视频| 欧美高清无遮挡| 国产精品一区二区三| 中文字幕亚洲欧美一区二区三区| 最近的2019中文字幕免费一页| 两个人的视频www国产精品| 亚洲二区中文字幕| 亚洲中国色老太| 成人黄色大片在线免费观看| 亚洲第一福利在线观看| 亚洲一区二区三区视频| 欧美视频专区一二在线观看| 55夜色66夜色国产精品视频| 国产精品日韩专区| www国产亚洲精品久久网站| 国产成人精品在线视频| 久久香蕉国产线看观看av| 国产精品美女久久| 日韩电影大全免费观看2023年上| 日韩在线视频中文字幕| **欧美日韩vr在线| 国产91精品青草社区| 尤物tv国产一区| 亚洲色图35p| 国产日产久久高清欧美一区| 亚洲a一级视频| 久久久噜久噜久久综合| 日韩成人性视频| 91在线观看免费网站| 欧美三级xxx| 欧美性生交xxxxxdddd| 日韩精品高清在线| 高清一区二区三区日本久| 日韩免费在线播放| 欧美专区在线视频| 亚洲视频一区二区| 欧美性视频在线| 成人午夜一级二级三级| 亚洲天天在线日亚洲洲精| 午夜美女久久久久爽久久| 欧美视频一区二区三区…| 97超级碰碰碰| 精品国产美女在线| 伊人伊人伊人久久| 欧美电影免费观看高清| 亚洲а∨天堂久久精品9966| 久久亚洲国产精品| 欧美精品在线网站| 欧美黑人巨大xxx极品| 国产精品亚洲аv天堂网| 福利微拍一区二区| 欧美黑人性视频| 久久久91精品| 国产精品视频内| 欧美精品第一页在线播放| 亚洲一区二区三区xxx视频| 97**国产露脸精品国产| 久久精品男人天堂|