矩阵的乘法在程序中作用有很多的体现。
前两天接触的那个题,可以使用矩阵连乘,然后,二分计算快速解答。由于是第一次接触,花了好一会才明白点所以然,这里小小的总结一下。
首先,使用矩阵连乘的好处:可以实现快速计算。
其次,如何把问题转化成矩阵连乘的形式。
这里举例说明。
拿fibonacci举例。
fibonacci公式:F[n]=F[n-1]+F[n-2];
可以先观察下这个式子:
1 1
【F[n-1],F[n-2] 】* 【 】 (囧~~~不会在这里插入数学公式,只好省略矩阵的大括号)
1 0
=【F[n-1]+F[n-2],F[n-1]】
这时还没有发现什么的话,再乘一次
1 1
【F[n-1]+F[n-2],F[n-1] *【 】
1 0
=【2F[n-1]+F[n-2],F[n-1]+F[n-2]】
也就是说,
1 1
F[1]=【0,1】* 【 】 的前一个项
1 0
即
1 1
F[n]=【0,1】 * 【 】 的n次幂的第一项
1 0
到此就把题目转化成了求矩阵乘法。其中,
1 1
【 】 是该矩阵乘法的初始矩阵。【0,1】的名字不知道叫什么,假定是结果矩阵
1 0
再者,初始矩阵的求法
这里举例说明,假设F[n]=3F[n-1]-F[n-2](牵扯m个F[n]初始矩阵就是m*m的矩阵,结果矩阵就是1*m的矩阵)
此时,m=2,由于肯定会知道F[0],F[1],F[2]这些初始值。即结果矩阵就是【F[n-1],F[n-2]】
利用矩阵的求法,可以计算出初始矩阵。
a b
【F[n-1],F[n-2]】*【 】观察可知,a=3,c=-1(第一行乘第一列得F[n]);b=1,d=0(第一行乘以第二列得F[n-1])。
c d
最后,如何实现快速计算。
利用二分法,计算矩阵的n次幂,由于m^2=(m*m),m^4=m^2*m^2,m^8=m^4*m^4,计算m^8只需要乘3次,可以节省很多时间。这里不再贴代码。
在这里附上我的Matrix模板
#include<iostream>
template<class T>
class Matrix
{
public:
Matrix();//构造函数
Matrix(const Matrix<T> &m);//拷贝构造函数
Matrix(int r,int c);//初始化一个矩阵,利用行和列
~Matrix(){delete m_elem;}
void display();
void trans();//转置
Matrix operator =(const Matrix<T> & m);
T & operator[](int pos);
Matrix operator +(const Matrix<T> & m);
Matrix operator -(const Matrix<T> & m);
Matrix operator *(const Matrix<T> & m);
bool operator ==(const Matrix<T> & m);
private:
T * m_elem;//指向元素的指针(类)
int row,column;
};
template<class T>
Matrix<T>::Matrix(int r,int c):row(r),column(c)
{
if (row==0||column==0)
{
m_elem=NULL;
}
else
{
m_elem= new T[row*column];
if (!m_elem)
{
cout<<"无法分配内存";
}
cout<<"创建一个"<<row<<"行"<<column<<"列的矩阵"<<endl;
for (int i=0;i<row;i++)
{
for (int j=0;j<column;j++)
{
cin>>m_elem[i*column+j];
}
}
}
}
template <class T>
Matrix<T>::Matrix()
{
cout<<"\n请输入行数 列数:";
cin>>row>>column;
m_elem = new T[row * column];
if (!m_elem)
{
cout<<"无法分配内存";
}
cout<<"创建一个"<<row<<"行"<<column<<"列的矩阵"<<endl;
for (int i=0;i<row;i++)
{
for (int j=0;j<column;j++)
{
cin>>m_elem[i*column+j];
}
}
}
template <class T>
Matrix<T>::Matrix(const Matrix<T> &m)
{
this->m_elem = new T[m.row * m.column];
if (!m_elem)
{
cout<<"无法分配内存";
}
row = m.row;
column = m.column;
memcpy(m_elem,m.m_elem,sizeof(T) * row * column);
}
template<class T>
T & Matrix<T>::operator[](int pos)
{
return m_elem[pos];
}
template<class T>
Matrix<T> Matrix<T>::operator +(const Matrix<T> & m)
{
Matrix<T> mresult(*this);
if (row!=Matrix::row||this->column!=Matrix::column)
{
cout<<"不同的矩阵不能相加";
}
else
{
for (int i=0;i<row*column;i++)
{
mresult.m_elem[i]+=m.m_elem[i];
}
}
return mresult;
}
template<class T>
Matrix<T> Matrix<T>::operator -(const Matrix<T> & m)
{
{
if (this.row!=Matrix::row||this->column!=Matrix::column)
{
cout<<"不同的矩阵不能相减";
}
else
{
Matrix<T> mresult(*this);
for (int i=0;i<row*column;i++)
{
mresult.m_elem[i]-=m.m_elem[i];
}
return mresult;
}
}
}
template<class T>
Matrix<T> Matrix<T>::operator *(const Matrix<T> & m)
{
Matrix<T> mresult(0,0);
mresult.m_elem=new T[row*m.column];
mresult.row=row;
mresult.column=m.column;
if (column!=m.row)
{
cout<<"不符合计算要求";
}
else
{
for (int i=0;i<row*m.column;i++)
{
int sum=0;
for (int j=0;j<=m.column;j++)
{
sum+=m_elem[i/m.column*column+j]*m.m_elem[m.column*j+(i%m.column)];
}
mresult.m_elem[i]=sum;
}
}
return mresult;
}
template<class T>
void Matrix<T>::trans()
{
Matrix<T> mresult(*this);
int num=row*column-1;
for (int i=0;i<=num;i++)
{
mresult.m_elem[i]=m_elem[(column*i)%num];
}
//return mresult;
}
template <class T>
Matrix<T> Matrix<T>::operator = (const Matrix<T> &m)
{
this->m_elem = new T[m.row * m.column];
if (!m_elem)
{
cout<<"无法分配内存";
}
row = m.row;
column = m.column;
memcpy(m_elem,m.m_elem,sizeof(T) * row * column);
return *this;
}
template<class T>
bool Matrix<T>::operator ==(const Matrix<T> & m)
{
if (row!=m.row||column!=m.column)
{
return false;
}
else
for (int i=0;i<row*column;i++)
{
if(m_elem[i]!=m.m_elem[i])
{
return false;
}
}
return true;
}
template <class T>
void Matrix<T>::display()
{
for (int i=0;i<row*column;i++)
{
cout<<m_elem[i]<<" ";
if (i&&i%column)
{
cout<<endl;
}
}
}