C++实现求解逆矩阵
2015-04-17 19:19
357 查看
利用C语言求解线性代数中求解逆矩阵的一类问题。
最近在学线代,其中有一个挺烦人的就是求解逆矩阵,虽然求逆矩阵不难,但我自己在解题的时候经常求错,所以就想能不能用算法来求解这一类的题目。
求解逆矩阵一般可以用初等行变换或伴随矩阵方法求解。
这里采用的是伴随矩阵方法。
思路很简单,先求矩阵A对应的行列式|A|,然后在求伴随矩阵即可,伴随矩阵可以用一个二维数组存放即可,注意一下伴随矩阵的元素排列方式,还有稍微注意一下在行列式中的元素下标和二维数组中的下标的不同。
接下来就是如何求解|A|的问题了,我没想太多,直接暴力求解吧,反正我需要求的阶数不会很多,所以即使算法不优,运行时间也不会很长。这里用的是余子式的方法,从第一行的第一个元素开始,得到对应的余子式,为了能够计算余子式的值,还需要继续对余子式求余子式,这里利用递归是一个很好的方法,会让思路很清晰。
至于伴随矩阵,实际上也是求解余子式的过程,这个过程和上述几乎是一样的。
下面是程序代码:carray.cpp
最近在学线代,其中有一个挺烦人的就是求解逆矩阵,虽然求逆矩阵不难,但我自己在解题的时候经常求错,所以就想能不能用算法来求解这一类的题目。
求解逆矩阵一般可以用初等行变换或伴随矩阵方法求解。
这里采用的是伴随矩阵方法。
思路很简单,先求矩阵A对应的行列式|A|,然后在求伴随矩阵即可,伴随矩阵可以用一个二维数组存放即可,注意一下伴随矩阵的元素排列方式,还有稍微注意一下在行列式中的元素下标和二维数组中的下标的不同。
接下来就是如何求解|A|的问题了,我没想太多,直接暴力求解吧,反正我需要求的阶数不会很多,所以即使算法不优,运行时间也不会很长。这里用的是余子式的方法,从第一行的第一个元素开始,得到对应的余子式,为了能够计算余子式的值,还需要继续对余子式求余子式,这里利用递归是一个很好的方法,会让思路很清晰。
至于伴随矩阵,实际上也是求解余子式的过程,这个过程和上述几乎是一样的。
下面是程序代码:carray.cpp
#include<iostream> #include<iomanip> using namespace std; #define N 10 //行列式的最大阶数 int getvalue(int a ,int n){ //计算|A| if(n==1) //递归结束条件,当n=1时,得到返回值a00; return a[0][0]; int res = 0,i,j,k,t,temp ; //定义一个临时数组,用于存放Ai的余子式 for(i=0;i<n;i++){ for(j=0;j<n-1;j++) for(k=0;k<n-1;k++) temp[j][k] = a[j+1][(k>=i)?k+1:k]; //每执行完一次j,k的循环,二位数组temp就是Ai的余子式 t = getvalue(temp,n-1); //递归,再求数组temp的第一行的余子式,直到余子式只有1个元素 if(i&1) //确定余子式的符号并进行行列式运算 res -= a[0][i]*t; else res += a[0][i]*t; } return res; //返回行列式计算结果 } void getAStar(int a ,int n,int yu ){ //计算每一行每一列的每个元素所对应的余子式,组成A* if(n==1) yu[0][0] = 1; //若阶数为1,则没有余子式 int i,j,k,t; int temp ; for(i=0;i<n;i++) for(j=0;j<n;j++){ for(k=0;k<n-1;k++) for(t=0;t<n-1;t++) temp[k][t] = a[k>=i?k+1:k][t>=j?t+1:t]; //到这里,temp存放的是a[0][0]的余子式(当然对应到数学时这里就是元素a11的余子式了) yu[j][i] = getvalue(temp,n-1); //同理,将余子式结果直接赋给yu[j][i]就可以了,这里为什么是ji而不是ij? //因为这是伴随矩阵的排列方式决定的 if((i+j)&1) yu[j][i] = - yu[j][i]; //同样要判断符号 } } int main() { int arr ,res ; int i,j; int n; cout<<"/*********************本程序可以求解10阶以内矩阵的逆矩阵**********************/"<<endl; cout<<"请输入矩阵的阶数:"<<endl; while(cin>>n && n){ cout<<"请输入矩阵:"<<endl; for(i=0;i<n;i++) for(j=0;j<n;j++) cin>>arr[i][j]; cout<<"所求得的逆矩阵为:"<<endl; int a = getvalue(arr,n); if(a==0) cout<<"can not transform!"<<endl; else{ getAStar(arr,n,res); for(i=0;i<n;i++){ for(j=0;j<n;j++){ double c=(double)res[i][j]/a;//A-1=1/|A|*A*; if(c==(int) c) cout<<setw(6)<<(int)c;//如果是整数则直接输出整数,每个字段长度为6 // cout<<setiosflags(ios::fixed)<<setiosflags(ios::right)<<setprecision(5); else cout<<setw(6)<<setiosflags(ios::fixed)<<setiosflags(ios::left)<<setprecision(3)<<c; //如果不是整数则输出浮点数,设置小数位数为3,小数点符号对齐 } cout<<endl; } } cout<<endl; cout<<"请输入矩阵的阶数:"<<endl; } return 0; }
相关文章推荐
- C++实现的求解多元一次方程示例
- 最大子数组问题-暴力求解-c++代码实现及运行实例结果
- C++实现牛顿迭代法求解f(x)=0
- C++ 自定义栈实现迷宫求解
- 动态规划之最长公共子序列的求解(C++实现)
- 各种线性方程组求解算法的C++实现
- C++中实现表达式的求解
- 逆矩阵介绍及C++/OpenCV/Eigen的三种实现
- C++实现求解最大公约数和最小公倍数
- 矩阵的LU分解求解线性方程组(C++实现)
- C++类模板定义与实现的分离—学习C++数据抽象和问题求解
- 面试题之丑数的C++实现求解(孤陋寡闻了,才知道丑数这么high的东东)
- 应用栈求解迷宫问题(C++实现)
- 最大子数组问题-暴力求解-c++代码实现及运行实例结果
- 回溯法求解数独(C++实现)
- 平方根法求解线性方程组(C++实现)
- 回溯法求解数独(C++实现)
- 动态规划 数塔问题求解 C++实现
- 矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)
- 迭代法求解线性方程组(C++实现)