一些動態規划問題的java實現


從上往下推公式,從下往上求解值。

一:矩陣鏈乘法,最小括號化方案,動態規划方程。   

                  0        如果i=j     

 m[i,j]  ={

                   min[i,k]+m[k+1,j]+pi-1pkpj          如果  i<j  

 

 

 

子問題涉及到子問題起始點和終止點 i , j 的 ,要用三層for循環。

第一層循環代表子問題的長度。

第二層for循環代表 子問題的 起始點。

第三層for循環在  子問題起始點和終止點之間找一個最優的分割點。 需用到動態規划公式。

 

1:求最小的矩陣,也就是兩個相鄰的矩陣 。兩個相鄰矩陣相乘之后,將會組成一個新的矩陣。行列為兩個相乘矩陣的左行右列。

2:求長度為3的矩陣的計算次數,

例如求30,35,15,5組成的3個矩陣的計算次數。

用到1的結果:  30,35,15 得到的矩陣A[30,15]和計算次數15750,  35,15,5得到的矩陣B [35,5] 和計算次數  2625。

[30,35,15,5]=min{(30*15*5+15750) , 30*35*5+2625}. 

以此類推...

java代碼:

package com.li.chapter15.class02;

/**
 * 矩陣鏈乘法:使用動態規划方法
 */
public class JuZhenLianChengFa {

    public static void main(String[] args){
        int[] p={30,35,15,5,10,20,25};  //p.length-1個矩陣
        matrixChainOrder(p);
    }

    public static void matrixChainOrder(int[] p) {  //p個矩陣,要用p.length+1個數字來表示。例如兩個矩陣相乘要用p0*p1*p2表示,p1是p0的列,p2的行
        int[][] m = new int[p.length-1][p.length-1];   //保存
//        int[][] s = new int[p.length - 1][p.length-1];

        for (int i = 0; i < m.length; i++) {
            m[i][i]=0;  //矩陣鏈長度為0時,乘積為0,m[j][j+0];
        }

        //p.length=3;
        for (int i = 1; i < p.length - 1; i++) {  // i 矩陣鏈的長度
            for (int j = 0; j < p.length-i-1; j++) {  //j從0到p.lenght-i-1,子問題的起始點   計算長度為i的矩陣鏈,所有的最優值。
                m[j][j+i]=Integer.MAX_VALUE;   //最大值。
                for (int k = j; k < j+i; k++) {   //求j到j+i這段長度乘積的最小值,  k是分割點
                    int value = m[j][k] + m[k + 1][j + i] + p[j]*p[k+1] * p[j+i+1];  //k為分割點時,乘積的大小
                    if (value < m[j][j + i]) {
                        m[j][j+i]=value;
//                        s[j][j + i]=k;  //j到j+i這段矩陣鏈最優分割點為 k
                    }
                }
            }
        }


        for (int i = 0; i < m.length; i++) {
            for (int j = 0; j < m[1].length; j++) {
                System.out.print(m[i][j]+"             ");
            }
            System.out.println("");
        }
        System.out.println(m[1][4]);
    }
}

 

 二:動態規划字符串匹配,  求字符串最大匹配長度。

     給定兩個字符串,str1="adef";   str2="bdfg";    求字符串最大的匹配個數。

將字符串化為字符數組進行匹配

 

1:判斷最后一個字符串是否匹配,如果不匹配,那么使用就是其中一個字符串減去最后一個字符,再重新匹配。取兩者中的較大值。

 

2:

求Match1  這兩個字符串匹配的長度。

      如果最后一個字符串相同。那么就是將兩個字符串都去掉最后一個字符,然后對剩余的字符串進行匹配得到匹配長度,然后加1(剛剛匹配的這一個字符)。  

 

以此類推,得到公式:

 

 java代碼:

package com.li.dynamic;

/**
 * @program: GradleTestUseSubModule
 * @author: Yafei Li
 * @create: 2018-08-02 17:14
 * https://www.cnblogs.com/wuyuegb2312/p/3281264.html
 *   字符串相似度。
 *   動態規划求解
 **/
public class ZiFuChuanXiangShiDu {
    public static void main(String[] args){
        String str1 = "wbdsakfieudfkdfg";
        String str2 = "isdfkjiekdjfkajg";

        char[] chars1 = str1.toCharArray();
        char[] chars2 = str2.toCharArray();

        int[][] arrs = new int[chars1.length][chars2.length];
        for (int i = 0; i < chars1.length; i++) {
            if (chars1[i] == chars2[0]) {
                arrs[i][0]=1;
            }
        }
        for (int i = 0; i < chars2.length; i++) {
            if (chars2[i] == chars1[0]) {
                arrs[0][i]=1;
            }
        }

        for (int i = 1; i < chars1.length; i++) {
            for (int j = 1; j < chars2.length; j++) {
                if (chars1[i] == chars2[j]) {
                    arrs[i][j] = arrs[i - 1][j - 1]+1;
                }else {
                    if (arrs[i - 1][j] > arrs[i][j - 1]) {
                        arrs[i][j]=arrs[i - 1][j];
                    }else {
                        arrs[i][j]=arrs[i][j-1];
                    }
                }
            }
        }

        for (int i = 0; i < arrs.length; i++) {
            for (int j = 0; j < arrs[0].length; j++) {
                System.out.print(arrs[i][j]+"   ");
            }
            System.out.println("");
        }
    }
}

 

 

 

 

 

 

 

 

 

 

              https://www.cnblogs.com/wuyuegb2312/p/3281264.html

       

 

動態規划,主要要找到一個問題的最優子結構。

      哪個變量作為子結構的變量。

變量:看哪個變量重復。

看哪個變量的集合能夠分出一個更小的子集。且完全無關。一般都有多個變量作為子結構的變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM