首页 > 编程语言 >算法设计与分析课-实验三-动态规划

算法设计与分析课-实验三-动态规划

时间:2022-09-22 23:45:01浏览次数:45  
标签:Ai 矩阵 相乘 算法 实验 数组 动态 规划

算法设计与分析课

实验三

第一题

矩阵连乘问题:

分析:该问题求矩阵连乘积最少乘次数,对于两个矩阵A(i行j列)和B(j行n列),他们相乘的乘次数为ijn,对于两个矩阵只有它们的列和行相等才能相乘。

用数组A接受矩阵的行列,对于一个矩阵An,其行为A[n-1],列为A[n],题目中给了Ai与Ai+1是可以相乘的。用数组M表示矩阵链相乘的最优解,例如M[i][j]表示从矩阵i到矩阵j的矩阵链相乘的最小计算次数。

利用动态规划求解,对于每一个矩阵链,其中的矩阵不断相乘,最后剩下两个矩阵相乘得到最后的矩阵,记它们在k处断开。但是k的值不确定,需要计算,所以动态规划就得到了解决公式。

如果i=j,则M[i][j]=0。

如果i<j,则M[i][j]等于min{M[i][k]+M[k+1][j]+Ai-1 * Ak * Aj}。

解决代码:

#include<iostream>
#include<cstring>
#define maxn 1000+5
#define inf 0x3f3f3f3f
using namespace std;

//利用动态规划求解
//用数组A接受矩阵的行列,对于一个矩阵An,其行为A[n-1],列为A[n],题目中给了Ai与Ai+1是可以相乘的
//用数组M表示矩阵链相乘的最优解,例如M[i][j]表示从矩阵i到矩阵j的矩阵链相乘的最小计算次数
//分析矩阵链的相乘,乘到最后只剩下两个矩阵相乘然后得到最终的矩阵,那么可以假设该矩阵链最后的相乘是从k处断开的
//但是k的值不确定,需要计算,所以动态规划就得到了解决公式
//如果i=j,则M[i][j]=0,如果i<j,则M[i][j]等于min{M[i][k]+M[k+1][j]+pi-1*pk*pj}
//其中p为矩阵的行列

int M[maxn][maxn];//记录矩阵链相乘的最优解
int S[maxn][maxn];//记录矩阵链相乘的断开点
int A[maxn];//记录矩阵
int n;//矩阵个数

void MatrixMultiply(int A[], int n, int M[][maxn], int S[maxn][maxn]);
void PrintWay(int S[][maxn], int l, int r);

int main()
{
    int n;
    cin>>n;
    for(int i=0; i<=n; i++) cin>>A[i];
    //memset(S, -1, sizeof(S));
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            S[i][j]=-1;
    MatrixMultiply(A, n, M, S);
    cout<<M[1][n]<<endl;
    //cout<<S[1][1]<<endl;
    PrintWay(S, 1, n);
    return 0;
}

void MatrixMultiply(int A[], int n, int M[][maxn], int S[maxn][maxn])
{
    //memset(M, inf, sizeof(M));
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            M[i][j]=inf;

    for(int i=1; i<=n; i++) M[i][i]=0;

    for(int len=2; len<=n; ++len)//矩阵链的长度
    {
        for(int i=1; i<=n-len+1; ++i)
        {
            int j=i+len-1;//最后一个矩阵的列

            /*不给数组M设置初值的写法,初始认为k为i
            M[i][j]=M[i][i]+M[i+1][j]+A[i-1]*A[i]*A[j];//可以不写M[i][j],因为该元素值为0
            S[i][j]=i;
            for(int k=i+1; k<j; ++k)
            {
                if(M[i][k]+M[k+1][j]+A[i-1]*A[k]*A[j]<M[i][j])
                {
                    M[i][j]=M[i][k]+M[k+1][j]+A[i-1]*A[k]*A[j];
                    S[i][j]=k;
                }
            }
            */
            for(int k=i; k<j; ++k)
            {
                if(M[i][k]+M[k+1][j]+A[i-1]*A[k]*A[j]<M[i][j])
                {
                    M[i][j]=M[i][k]+M[k+1][j]+A[i-1]*A[k]*A[j];
                    S[i][j]=k;
                }
            }
        }
    }
}

void PrintWay(int S[][maxn], int l, int r)
{
    if(S[l][r]!=-1)
    {
        PrintWay(S, l, S[l][r]);
        PrintWay(S, S[l][r]+1, r);
        cout<<"Multiply A"<<l<<","<<S[l][r]<<" and A"<<S[l][r]+1<<","<<r<<endl;
    }
    else
    {
        return ;
    }
}

标签:Ai,矩阵,相乘,算法,实验,数组,动态,规划
From: https://www.cnblogs.com/HD0117/p/16721207.html

相关文章

  • 实验2:Open vSwitch虚拟交换机实践
    实验2:OpenvSwitch虚拟交换机实践一、实验目的能够对OpenvSwitch进行基本操作;能够通过命令行终端使用OVS命令操作OpenvSwitch交换机,管理流表;能够通过Mininet的Pytho......
  • 实验环境安装配置 + 实验1:SDN拓扑实践
    一、实验目的熟悉实验环境熟悉Linux基本操作二、实验要求(一)任务请根据实验环境安装文档,完成特定开源软件的安装(二)实验报告请用Markdown排版,提交在博客园班级作业区,......
  • CSP 2022 备战 贪心算法
    基本思路:1.建立数学模型来描述问题2.把求解的问题分成若干个子问题3.对每一子问题求解,得到子问题的局部最优解4.把子问题的局部最优解合并成一个解贪心的使用前提:局部......
  • Python实验报告(第四周)
    实验4:Python序列的应用一、实验目的和要求学会应用列表、元组、字典等序列;二、实验环境软件版本:Python3.1064_bit三、实验过程1、实例1:输出每日一贴(1)在IDLE中创建......
  • 实验2:Open vSwitch虚拟交换机实践
    实验2:OpenvSwitch虚拟交换机实践一、实验目的1.能够对OpenvSwitch进行基本操作;2.能够通过命令行终端使用OVS命令操作OpenvSwitch交换机,管理流表;3.能够通过Mininet的......
  • UI 动态加载
    1.UI动态加载1.原理介绍在实际项目开发过程中,UI界面制作好以后会拖拽成为一个Prefab资源,和Scene场景分离,在实际加载到该场景的时候,动态的加载显示UI界面。这样可......
  • 实验2:Open vSwitch虚拟交换机实践
    实验2:OpenvSwitch虚拟交换机实践1.创建OVS交换机a)执行ovs-vsctlshow命令b)p0和p1连通性测试2.使用Mininet搭建SDN拓扑a)开启MininetCLI并执行pingallb)查看OVS......
  • KMP算法
    朴素的模式匹配算法朴素算法就是以主串的每一个字符作为子串的开头,与要匹配的字符串(称为模式串)进行匹配,匹配失败则主串退回到这次匹配首位的下一位,重新进行匹配。主......
  • 实验2:Open vSwitch虚拟交换机实践
    实验2:OpenvSwitch虚拟交换机实践(一)基本要求a)/home/用户名/学号/lab2/目录下执行ovs-vsctlshow命令、以及p0和p1连通性测试的执行结果截图;b)/home/用户名/学号......
  • python基础__十大经典排序算法
    用Python实现十大经典排序算法!排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序......