鱼C论坛

 找回密码
 立即注册
查看: 2998|回复: 0

[技术交流] 矩阵连乘的DP,两种方法(自下至上、自顶至下)

[复制链接]
发表于 2014-3-26 22:41:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 andalousie 于 2014-3-26 22:42 编辑

基本上百度一下都可以搜到矩阵连乘的算法。大家写的都差不多是同一个思路(bottom-up DP,自下而上的动态规划)。这里再提供一个速度相仿的自上而下(top-down)的解法。代码属于C++。
// See the Cormen book for details of the following algorithm
#include<iostream>
#include<cstdio>
#include<climits>

class MatrixChain
{
        int     n;
        int ** m;
        int ** s;
public:
        MatrixChain(int size)
                :n(size)
        {
                /* For simplicity of the program, one extra row and one extra column are
       allocated in m[][].  0th row and 0th column of m[][] are not used */
                m = new int* [n+1];
                s = new int* [n+1];
                for (int t = 0; t <= n; ++t)
                {
                        m[t] = new int[n+1];
                        s[t] = new int[n+1];
                }
        }
        ~MatrixChain()
        {
                for (int t = 0; t <= n; ++t)
                {
                        delete [] m[t];
                        delete [] s[t];
                }
                delete [] s;
                delete [] m;
        }
        int MatrixChainOrder(int p[]);
        int MatrixChainOrderTD(int p[]);
        void traceback(int i, int j);
        int topdown(int p[], int i, int j);
};

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChain::MatrixChainOrder(int p[])
{
    int i, j, k, L, q;

    /* m[i,j] = Minimum number of scalar multiplications needed to compute
       the matrix A[i]A[i+1]...A[j] = A[i..j] where dimention of A[i] is
       p[i-1] x p[i] */

    // cost is zero when multiplying one matrix.
    for (i = 1; i <= n; i++)
        m[i][i] = 0;
 
    // L is chain length.  
    for (L=2; L<=n; L++)   
    {
        for (i=1; i<=n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;
            for (k=i; k<=j-1; k++)
            {
                // q = cost/scalar multiplications
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                                {
                    m[i][j] = q;
                                        s[i][j] = k;
                                }
            }
        }
    }
    return m[1][n];
}

// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChain::MatrixChainOrderTD(int p[])
{
    for (int i = 1; i <= n; i++)
        m[i][i] = 0;
        for (int u = 0; u <= n; ++u)
                for (int v = 0; v <= n; ++v)
                        s[u][v] = 0;
 
    int result = topdown(p, 1, n);
    return result;
}

void MatrixChain::traceback(int i, int j)
{
        if(i == j) return;
        traceback(i, s[i][j]);
        traceback(s[i][j]+1, j);
        std::cout << "A[" << i << ',' <<s[i][j]
                << "] * A[" << s[i][j]+1 << ',' << j
                << "]\n";
}

int MatrixChain::topdown(int p[], int i, int j)
{
        if(i != j)
        {
                if(s[i][j]) return m[i][j];
                m[i][j] = INT_MAX;
                int q;
                for(int k = i; k < j; ++k)
                {
                        q = topdown(p, i, k) + topdown(p, k + 1, j) + p[i-1]*p[k]*p[j];
                        if (q < m[i][j])
                        {
                                m[i][j] = q;
                                s[i][j] = k;
                        }
                }
        }
        return m[i][j];
}

int main()
{
        int arr[] = {3023, 3533, 155, 203, 2573, 3093};
        int size = sizeof(arr)/sizeof(arr[0]) - 1;
        MatrixChain mc(size);
        printf("Minimum number of multiplications is %d \n",
                       mc.MatrixChainOrder(arr));
        printf("Minimum number of multiplications is %d \n",
                       mc.MatrixChainOrderTD(arr));
        mc.traceback(1, size);
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 22:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表