• 算法复习周------“动态规划之‘矩阵连乘’”


    问题描述:  设有三个矩阵 A[a][b]、B[b][c]、C[c][d]。这个时候我们将ABC排列并相乘:A*B*C,这个时候我们会发现我们有两种不同的矩阵乘法次序——(A*B)*C与A*(B*C)。这个时候我们若要求解矩阵连乘的数乘次序——我们可以分为两个情况

    ①(A*B)*C——这个时候A*B的连乘次序为a*b*c(因为A的矩阵是a行b列,B的矩阵是b行c列,所以这两个矩阵每一次行列相乘都进行b次乘积,并且他们共进行a*c次乘法运算)当A*B后得到的新矩阵为A'[a][c]此时要计算A'与C的次序,同理为a*c*d。这个时候我们就得到乘积次序的和为a*b*c+a*c*d

    ②A*(B*C)——这个时候我们先求B*C,由①中结论我们知道B*C为b*c*d,得B'[b][d],此时A*B'为a*b*d,得乘积和为b*c*d+a*b*d

    由次我们知道同一个矩阵相乘括号次序不同得到的结果不同。为了更好理解下面我给出一道例题:

      

                            

     算法描述:在这个算法中,我们的目的是为了求一串数组的最小乘积次数。所以我们调用动态规划的思想来解决这类问题。在动态规划的过程中,我们需要建立两组二维数组,一个用来记录每一个子问题的最优解,另一组用来记录每一组最优解断开的位置。

    在写算法的时候我们设置一个P的一位数组,假设有n个矩阵,那么P[0]代表第一个矩阵的行,P[1]代表第一个矩阵的列......依次递推即P[N-1]代表第N个矩阵的行值,P[N]代表第N个矩阵的列值。

    之后我们得到递推公式:————解释下这个公式:当i=j时也就意味着当前矩阵列只有一个矩阵, 此时肯定不涉及相乘的问题,所以必须是0呀。

    当i<j时,我们将当前矩阵的断点设置为k,也就是第i个矩阵到第k个矩阵为一组,k+1到j为一组。遍历所有情况求解出最小的那个值(因为m[i][k]与m[k+1][j]的情况我们在求解这个问题前已经得出,所以直接拿来用就好),最后别忘了把最后一个矩阵的乘积次数加上(这个很好记——矩阵链的第一个数的行*最后一个数的列*断开位置的列)下面我给出这两个二维数组的具体过程

    先处理对角线的值,之后向右以此写15750、2625、750。。。按照对角线的顺序来写,同理s矩阵中存入的是最优解断开位置,与m顺序相同。之后我们知道m[1][6]就是我们要求的最优解。

    代码:

    int MatrixChain(int n,int **m,int **s,int *p)  
    {  
        for(int i=1; i<=n; i++)  //只有一个矩阵的情况
        {  
            m[i][i] = 0;  
        }  
        for(int r=2; r<=n; r++) 
        {  
            for(int i=1; i<=n-r+1; i++)//
            {  
                int j = i+r-1;//计算前边界为r,链长为r的链的后边界    
      
                m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];//先假设这样分是最优解,后面会不断更新
      
                s[i][j] = i;  
      
                for(int k=i+1; k<j; k++)  
                {  
                    //将链ij划分为( A[i:k] )* (A[k+1:j])     
                    int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];  
                    if(t<m[i][j])  //不断更新最优解
                    {  
                        m[i][j] = t;  
                        s[i][j] = k;  
                    }  
                }  
            }  
        }  
        return m[1][L-1];  
    }  

     

    不过动态规划的问题还是要多加练习的,如果同学们有想练手的话可以去“计蒜课”中写一下“沙子的质量”——————我对于这道题目也写了一些题解http://www.cnblogs.com/Pinging/p/7684638.html大家可以去看一看

     ————————————————————Made By Pinging

  • 相关阅读:
    putty如何退出全屏模式
    maven项目如何生成war文件
    使用web.xml方式加载Spring时,获取Spring context的两种方式
    Mybatis 示例之 SelectKey
    psql主主复制
    【转】angular使用代理解决跨域
    Error: EACCES: permission denied when trying to install ESLint using npm
    Run Code Once on First Load (Concurrency Safe)
    [转]对于BIO/NIO/AIO,你还只停留在烧开水的水平吗
    golang 时间的比较,time.Time的初始值?
  • 原文地址:https://www.cnblogs.com/Pinging/p/7898732.html
Copyright © 2020-2023  润新知