2.动态规划的矩阵连乘问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HackQ_sxj/article/details/80571910

问题描述: 利用动态规划方法,求解下面矩阵连乘A1A2A3A4所需的最少数乘次数,并给出最佳乘积序列,要求给出求解步骤,给出最优值数组和最佳断开位置数组。其中,pi-1 为矩阵Ai的行数,pi为矩阵Ai的列数,四个矩阵中各矩阵维数分别如下:


解题思想:计算A[i:j]矩阵的最小连乘1<=i<=j<=n,所需要的最小数乘次数为m[i, j]。

i=j时,A[i:j]=Ai,因此,m[i,i]=0i=1,2,,n

i<j时,若A[i:j]的最优次序在AkAk+1间断开,则m[i, j] = min{m[i, k]+m[k+1, j]+pi-1pk[j}, i<=k<=j.

代码如下:

#include <iostream>
#include <stdlib.h>
using namespace std;

int MatrixChain(int *p, int n, int **m, int **s)
{
    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;
        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++)
        {
            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][n];
}

void Traceback(int i, int j, int **s)
{
    if (i == j)
    {
        cout << "A" << i;
        return;
    }
    cout << "(";
    Traceback(i, s[i][j], s);
    Traceback(s[i][j] + 1, j, s);
    cout << ")";
}

int main(){
   int n = 4;
   int p[5] = {10,100,5,50,10};
   int **m = new int*[n+1];
   int **s = new int*[n+1];
   for (int i = 0; i < n+1; i++)
    {
        m[i] = new int[n+1];
        s[i] = new int[n+1];
    }
   int x = MatrixChain(p, n, m, s);
   cout<<"最小连乘数为:"<<x<<endl;
   cout<<"最优解为:"<<endl;
   Traceback(1, n, s);
   for (int i = 0; i < n+1; i++)
    {
        delete[] m[i];
        delete[] s[i];
    }
    delete[]m;
    delete[]s;
   return 0;
}

结果:




猜你喜欢

转载自blog.csdn.net/HackQ_sxj/article/details/80571910