矩阵连乘 动态规划(转载)

动态规划表格法矩阵连乘问题(含填表详细过程及说明) 3.7 矩阵连乘(Matrix chain multiplication) 3.7.1 问题描述 求多个矩阵连乘的最优次序,使得所需的乘法次数最少,并求出所需的乘法次数。 3.7.2 算法思路 跟以往的动态规划解题思路相同,要求A1~A5的连乘,就先求A1A2的,再求A1A2A3的… 我们需要填写下列这张表,它记录了每个子问题的值 按照上图的填写思路,我们最终填完所有的表,即下图的左表。 而下图的右侧表格代表的是括号的位置,比如我们在填(A1,A3)这格时,发现橙色的,也就是A1(A2A3)的乘法次数最少 阅读详情

一、问题描述

         给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。要算出这n个矩阵的连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。完全加括号的矩阵连乘积可递归地定义为:

        (1)单个矩阵是完全加括号的;

        (2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,即A=(BC)。

        例如,矩阵连乘积A1A2A3A4有5种不同的完全加括号的方式:(A1(A2(A3A4))),(A1((A2A3)A4)),((A1A2)(A3A4)),((A1(A2A3))A4),(((A1A2)A3)A4)。每一种完全加括号的方式对应于一个矩阵连乘积的计算次序,这决定着作乘积所需要的计算量。若A是一个p×q矩阵,B是一个q×r矩阵,则计算其乘积C=AB的标准算法中,需要进行pqr次数乘。

        为了说明在计算矩阵连乘积时,加括号方式对整个计算量的影响,先考察3个矩阵{A1,A2,A3}连乘的情况。设这三个矩阵的维数分别为10×100,100×5,5×50。加括号的方式只有两种:((A1A2)A3),(A1(A2A3)),第一种方式需要的数乘次数为10×100×5+10×5×50=7500,第二种方式需要的数乘次数为100×5×50+10×100×50=75000。第二种加括号方式的计算量时第一种方式计算量的10倍。由此可见,在计算矩阵连乘积时,加括号方式,即计算次序对计算量有很大的影响。于是,自然提出矩阵连乘积的最优计算次序问题,即对于给定的相继n个矩阵{A1,A2,…,An}(其中矩阵Ai的维数为pi-1×pi,i=1,2,…,n),如何确定计算矩阵连乘积A1A2…An的计算次序(完全加括号方式),使得依此次序计算矩阵连乘积需要的数乘次数最少。

        穷举搜索法的计算量太大,它不是一个有效的算法,本实验采用动态规划算法解矩阵连乘积的最优计算次序问题。

二、算法思路

         动态规划算法的基本思想是将待求解问题分成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,动态规划法经分解得到的子问题往往不是相互独立的,前一子问题的解为后一子问题的解提供有用的信息,可以用一个表来记录所有已解决的子问题的答案,不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。

        本实验的算法思路是:

        1、计算最优值算法MatrixChain():建立两张表(即程序中的**m和**s,利用二维指针存放),一张表存储矩阵相乘的最小运算量,主对角线上的值为0,依次求2个矩阵、3个矩阵…、直到n个矩阵相乘的最小运算量,其中每次矩阵相乘的最小运算量都在上一次矩阵相乘的最小运算量的基础上求得,最后一次求得的值即为n个矩阵相乘的最小运算量;另一张表存储最优断开位置。

        2、输出矩阵结合方式算法Traceback():矩阵结合即是给矩阵加括号,打印出矩阵结合方式,由递归过程Traceback()完成。分三种情况:

        (1)只有一个矩阵,则只需打印出A1

        (2)有两个矩阵,则需打印出(A1A2);

        (3)对于矩阵数目大于2,则应该调用递归过程Traceback()两次,构造出最优加括号方式。
 

三、实验源程序

         建立一个矩阵的类Matrix。

         Matrix.h代码
         Matrix.cpp代码

#ifndef MATRIX_H
#define MATRIX_H


class Matrix
{
public
:
    Matrix();         
//构造函数

    ~Matrix();        //析构函数
    bool Run();       //运行接口函数
private:
    
int W;         //记录矩阵的个数

    int **m;       //存放最优值,即最小运算量
    int **s;       //断开位置
    int *p;        //存放

    
bool Input();  //处理输入
    bool MatrixChain();//计算最优值算法
    void Traceback(int i,int j,int **s);   //输出矩阵加括号的方式
}
;

#endif

  

#define N 50
#include 
<iostream.h>
#include 
<stdlib.h>
#include 
"Matrix.h"

//构造函数,作变量初始化工作,为指针分配内存空间
Matrix::Matrix()
{
    W
=0
;
    m 
= new int*
[N];
    s 
= new int*
[N];
    
for(int i=0; i<N ; i++
)
    
{
        m[i] 
= new int
[N];
        s[i] 
= new int
[N];
    }

    p 
= new int[N];
}


//析构函数,释放内存
Matrix::~Matrix()
{
    
for(int i=0; i<N ; i++
)
    
{
        delete []m[i];
        delete []s[i];
    }

    delete []m;
    delete []s;
    delete []p;
}


//处理键盘输入
bool Matrix::Input()
{
    
int
 w;
    cout
<<"矩阵个数:"
;
    cin
>>
w;
    W 
=
 w;
    cout
<<"输入矩阵A1维数"<<""
;
    cin
>>p[0]>>p[1
];
    
for(int i=2 ; i<=W ; i++
)
    
{
        
int m = p[i-1
];
        cout
<<"输入矩阵A"<<i<<"维数:"
;
        cin
>>p[i-1]>>
p[i];
        
if(p[i-1!=
 m)
        
{
            cout
<<endl<<"维数不对,矩阵不可乘!"<<
endl;
            exit(
1
);
        }

        
//cout<<endl;
    }

    
if(p!=NULL)
        
return true
;
    
else

        
return false;
}


//计算最优值算法
bool Matrix::MatrixChain()
{
    
if(NULL ==
 p)
        
return false
;
    
for(int i=1;i<=W;i++
)
        m[i][i]
=0
;
    
for(int r=2;r<=W;r++
)
        
for(int i=1;i<=W-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 true;
}


//输出矩阵结合方式,加括号
void Matrix::Traceback(int i,int j,int **s)
{
    
if(i ==
 j)
    
{
        cout
<<"A"<<
i;
    }

    
else if(i+1 == j)
    
{
        cout
<<"(A"<<i<<"A"<<j<<")"
;
    }

    
else
    
{
        cout
<<"("
;
        Traceback(i,s[i][j],s);
        Traceback(s[i][j]
+1
,j,s);
        cout
<<")"
;
    }

}


bool Matrix::Run()
{
    
if
(Matrix::Input())
    
{
        
if
(Matrix::MatrixChain())
        
{
            Matrix::Traceback(
1
,W,s);
            cout
<<
endl;
            
return true
;
        }

        
else 
            
return false
;
    }

    
else
        
return false;
}

    main.cpp代码

#include "Matrix.h"

void main()
{
    Matrix m;
    m.Run();
}

动态规划矩阵连乘问题 大家好,我是连人。本期我们分享矩阵连乘问题。 在矩阵乘法中,不同的加括号方式的计算顺序可能会有不同的计算次数。 例如A:10×100,B:100×5,C:5×50 以(AB)C计算时,需要10×100×5+10×5×50=7500 以A(BC)计算时,需要100×5×50+10×100×50=75000 显然第一种计算方式计算次数更少,矩阵连乘问题就是求出最佳匹配的顺序。 我们将矩阵的维数记录到数... 阅读详情

相关推荐

MTK Tunning ISP 模块面试总结

ISP面试问答

m0_72053187的博客 4436

矩阵连乘积的加括号方式数

给定n个矩阵{A1,…,An},其中Ai和Ai+1可乘,i=1,2,…,n-1。考察矩阵连乘积加括弧的方式数。 如四个矩阵连乘积A1A2A3A4,共有五种不同的加括弧方式: ( A1 ( A2 ( A3 A4 ) ) ) ( A1 ( ( A2 A3 ) A4 ) ) ( ( A1A2 ) ( A3 A4 ) ) ( A1 ( A2 A3 ) A4 ) ( ( ( A1 A2 ) A3 ) A4 )

浅谈python反序列化漏洞

0x01 python序列化与反序列化 Python 的序列化和反序列化是将一个类对象向字节流转化从而进行存储和传输,然后使用的时候再将字节流转化回原始的对象的一个过程。python中的序列化操作是通过pickle模块,而该模块主要包含l dumps将dict转化为str格式,loads将str格式转化为dict格式。 dump和load与文件操作结合起来, pickle.dump(obj, f...

Lethe's Blog 3183

矩阵连乘最佳加括号方式-动态规划算法

一、问题描述 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。要算出这n个矩阵连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘...

weixin_30381317的博客 1567

矩阵连乘(DP)

Description 给定n个矩阵{ A1,A2,…,An },保证Ai与Ai+1是可乘的,i = 1,2,…,n-1。考察这n个矩阵连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。现要求设计一个高效的算法,对给定的n个矩阵确定一个计算次序使得总的乘法次数最少,并输出该最优值。 Input 输入的第一行是单独一个整数T,表示案例的数目。每个案例的第一行是单独一个n ( 1 ≤ n ≤ 600 ),表示矩阵的个数。接下来第n行

lili的点点滴滴 460

3-1 矩阵连乘问题(动态规划和备忘录方法)

给定n个矩阵:A1,A2,…,An,其中Ai与Ai+1是可乘的,i=1,2…,n-1。考察这n个矩阵连乘积A1A2…An。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。

我走的每一步都算数 1082

动态规划算法---矩阵连乘(C语言)

问题描述:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。 一 分析最优解的性质与结构 最优解也就是计算A[1:n]的最优次序,可以假设这个最优解在第k处断开,1<=k<j,则A[1:j]是最优的,那么A[1,k]和A[k+1:j]也是相应矩阵连乘的最优解。 关键在于...

weixin_44903715的博客 1万+

n1 c语言程序,C语言 动态规划法求解 矩阵连乘 N1 <代码在最后,版权所有,转载请声明!>...

问题:给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。计算这n个矩阵连乘积。由于矩阵乘法满足结合律,故计算矩阵连乘积可以由许多不同的计算次序。计算次序不同计算连乘积的计算量也不同。运用动态规划法思想给出你认为合理的计算矩阵连乘积最少次数的方案。分析:1.动态规划是一种将问题实例分解为更小的、相似的子问题,并存储子问题的解而避免计算重复的子问题,以解决最...

weixin_36095188的博客 377

矩阵连乘 动态规划 详解

矩阵连乘问题----动态规划(转载): 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。 解答:我们按照动态规划几个步骤来分析: (1)找出最优解的性质,刻画其特征结构 对于矩阵连乘问题,最优解就是找到一种计算顺序,使得计算次数最少。 令m[i][j]表示第i个矩阵

tmljs1988的专栏 2万+

矩阵连乘详解

本博客转载自 http://blog.sina.com.cn/s/blog_64018c250100s123.html 矩阵连乘详解 --crystal yi 既然这篇文章叫做矩阵连乘详解,那么我就不能辜负详解这两个字,只有把一个原来不懂的的人弄懂了,才叫详解。 言归正传,首先让我们复习一下矩阵连乘的有关知...

qq_40911292的博客 4927

算法重拾之路——矩阵连乘问题

算法重拾之路 矩阵连乘问题

继续激情,继续奋斗。 2894

动态规划矩阵连乘

本博客转载自 https://www.cnblogs.com/hzhtracy/p/4427870.html 动态规划矩阵连乘 以下内容参考(摘抄)《算法设计与分析》,王晓东编著,清华大学出版社2003年1月第1版。 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。考察这n个矩阵连乘积A1A2…An。由于矩阵乘法满足结合律,故计算矩阵连乘积可...

qq_40911292的博客 429

动态规划-矩阵连乘问题

矩阵连乘问题是动态规划的重要例子,弄了一个晚上加一个小时终于AC了。。。。感觉自己很拙。。。。。 矩阵链乘问题 输入: 共两行 第一行 N ( 1<=N<=100 ),代表矩阵个数。 第二行有 N+1 个数,分别为 A1 、 A2 …… An+1 ( 1<=Ak<=10 ), Ak 和 Ak+1 代表第 k 个矩阵是个 Ak X Ak+1 形的。 输出: ...

weixin_34370347的博客 383

矩阵连乘问题

给定n个矩阵A1,A2.......An,其中Ai与Ai+1是可乘的。     由于矩阵的乘法满足结合律,故计算矩阵连乘积可以有许多不同的计算次序。这中计算次序可以用加括号的方式来确定。例如,矩阵连乘积A1A2A3A4可以有一下5种不同的完全加括号方式:     (A1(A2(A3A4)))     (A1((A2A3)A4))     ((A1A2)(A3A4))     ((A1(

simmerlee的专栏 1万+

算法导论—矩阵链乘法(动态规划)

进行独立求解,并且要满足最优括号化方案,最后将子问题的最优解合并就可以得到问题的最优解。.由于最优分割点必其中,我们只需要检查所有可能的情况,推到最优者即可。设矩阵Ai···j 的大小为pi-1×pi ,那么。数乘次数的最小值,那么原问题的最优解——计算。最小代价括号化方案的递归求解公式变为。之间的整数),也就是说我们首先计算矩阵。是已知的,但实际上我们并不知道。乘积的结果矩阵,如果问题是非凡的,即。,然后再计算他们的乘积得到最终结果。进行括号化,我们就必须在某个。中得到的最优子结构来计算。

我们都是被分成两半的人,一边热爱生活,一边憎恨生活。面对生活,我们总是在矛盾的两端摇摆,在反复的矛盾和犹豫中,一边踉跄前行,一边重振旗鼓。我渴望改变,渴望变得更好,渴望找到出口……就像一个溺水人的挣扎,就像一个救生圈。我是一个矛盾集合体,想要变得快乐,但是 1155

动态规划——矩阵连乘

由于矩阵的乘法满足结合律,故计算矩阵连乘积可以有许多不同的计算次序。这中计算次序可以用加括号的方式来确定。例如,矩阵连乘积A1A2A3A4可以有一下5种不同的完全加括号方式:(A1(A2(A3A4)))(A1((A2A3)A4))((A1A2)(A3A4))((A1(A2A3))A4)(((A1A2)A3)A4)矩阵A和B可乘的条件是矩阵A的列数等于矩阵B的行数。若A是一个p*q的矩阵,B是一个q

u011040361的专栏 1780

矩阵连乘(C语言)

矩阵连乘(C语言) 参考链接:https://blog.csdn.net/qq_32919451/article/details/80643118 问题描述 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10 * 100,100 * 5和5 * 50,采用(A1A2)A3,乘法次数为101005+10550=7500次,而采用A1

Weightlessly的博客 7893

输出矩阵连乘所有的完全加括号形式

例如说,有四个矩阵ABCD相乘,那么所有的完全加括号结果为(A((BC)D)) (A(B(CD))) ((AB)(CD)) (((AB)C)D) (A(BC))D)。要求输出n个矩阵连乘所有的完全加括号结果。 解决方法一 基本思想:首先从1,2,3,4个矩阵的角度来归纳。如果只有一个矩阵A,那么很明显所有的完全加括号结果就是A本身。如果有两个矩阵A,B相乘,很明显所有的完全加括号结果就是AB。...

vandance的博客 6089

动态规划求解矩阵连乘

基本思想 动态规划算法与分治法类似,其基本思想是将待求解的问题分解成若干子问题,先求解子问题,再结合子问题的解得到原问题的解。与分治法不同的是,适合用动态规划法求解的问题经分解求解的子问题往往不是相互独立的。 若用分治法来解这类问题,则分解得到的子问题数目太多,以致最后解决原问题需要耗费指数级时间。然而,不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问斯被重复计算了许多次。如果能够保存已解决的子问题的答案,在需要时再找出已求得的答案,这样可以避免大量的重复计算,从而得到多项式时间算法。为了达到

weixin_53522240的博客 1万+

PRD产品需求文档案例 23份

需求文档,产品经理!收集了23份需求文档,满足产品经理平时工作需求!

上一篇: 黑客解密(转)
下一篇: oracle 中的 rownum
jingWithme
博客等级 码龄16年 2粉丝 11原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值