算法複習之動態規劃

算法對於我們程序員來說猶如飯碗一樣,重中之重。一個有效的算法,可以解決你大部分的問題點。因此,在這邊從頭複習了一下算法------動態規劃。

動態規劃等基本概念可以查看該博主寫的內容

https://blog.csdn.net/misayaaaaa/article/details/71794620

寫的很詳細,謝謝博主。

這邊補充點自己的理解和想法。

動態規劃算法簡單點的意思就是迭代法。

相對自上而下的遞歸算法來說,迭代法的效率要高。所以可以將動態規劃算法簡單理解成迭代法。

要規範的解釋動態規劃,請看官點擊上面的鏈接細細品嚐。

 

它就是把一個問題轉化成多個過程或者多個階段,利用各個階段之間的關係,來逐個求解,以此來解決這類問題。

動態規劃經典例子

0-1揹包問題,最短路徑問題,網組的無交叉子集。

來看下 最短路徑問題實例:

這裏我們需要事先定義下

假設圖有n個定點,且從1到n編號。c(i,j,k)表示從定點i到j的一條最短路徑的長度,其中間定點的編號不都大於k。因此,如果邊(i,j)存在,則c(i,j,0)是該邊的長度。若i=j,則c(i,j,0)。如果邊(i,j)不存在,則c(i,j,0)等於無窮大.c(i,j,n)代表從i到j的最短路徑的長度。

 

例如:

若k=0,1,2,3,則c(1,3,k)=∞,c(1,3,4)=28;若k=5,6,7,則c(1,3,k)=10。以此類推可以得到遞歸公式

c(i,j,k)=min{c(i,j,k-1),c(i,k,k-1)+c(k,j,k-1)},k>0

下面用代碼實現

template<class T>
void alPairs(T **c, int **kay)
{
    //動態設計所有定點對之間的最短路徑算法
    //對所有i和j,計算c[i][j]和kay[i][j]
    //這裏的代碼用來檢驗*this是否爲加權圖
    //初始化c[i][j]=c(i,j,0)
    for(int i = 1;i<=n; ++i){
        for(int j = 1; j <= n; ++j){
            c[i][j]=a[i][j];
            kay[i][j] = 0;
            if(i==j)
                c[i][j] = 0;
        }
    }
    
    //計算c[i][j] = c(i,j,k)
    for(int k = 1;k<=n;++k){
        for(int i = 1;i<=n; ++i){
            for(int j = 1; j <= n; ++j){
                if(c[i][k] != noEdge && c[k][j] != noEdge && (c[i][j] == noEdge || c[i][j] >(c[i][k]+c[k][j]))){
                    c[i][j] = c[i][k] + c[k][j];
                    kay[i][j] = k;
                }
            }
        }
    }
        

}

 

其中函數allPairs在c中返回最短路徑的長度。若從i到j無桐廬,則c[i][j]的值爲noEdge.函數allPairs還計算kay[i][j],它是從i到j的最短路徑中最大的k值。kay值可以用來構建從一個頂點到另一個頂點的最短路徑

 

以上程序是來自數據結構,算法與應用C++語言描述中的程序,方便理解。

如果錯誤請各位更正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章