大致过程:
- |A|!=0
- 左下角变换0(若对角不为1元素下方元素为1交换两行.)
- 对角元素变1
- 右上角变换0
源码:
#include<iostream>
#include<iomanip>
using namespace std;
//By Vove.
//左下角变换0 若对角不为1元素下方元素为1交换两行
//对角变1
//右上角变换0
void LD_triangle(float temp[6][12],int n);
void RU_triangle(float temp[6][12],int n);
void Aii_Cto_1(float temp[6][12],int n);
void Display(float A[6][12],int m,int n);
int Find(float temp[6][12],int i,int n);
void Swap(float temp[6][12],int i,int j,int n);
class Matrix{
public:
Matrix(){
n=9;
for(int i=0;i<6;i++)
for(int j=0;j<12;j++)
A[i][j]=0;
Det_A=0;
}
void Conversion();
void Input();
bool Cal_DetA();
friend void Save_To_Result(float temp[6][12],Matrix &D);
void Cheak_IsSolvable();
void Out_Result();
private:
int n; //阶
float A[6][12]; //矩阵
float result[6][6]; //逆矩阵结果
float Det_A; //|A|值 :是否存在逆矩阵
};
int main(){
cout<<"\n\t\t-------求逆矩阵(初等变换法)-------"<<endl<<endl;
while(1){
Matrix D;
D.Input();
D.Cheak_IsSolvable(); //可解
D.Conversion(); //变换
D.Out_Result(); //输出
}
return 1;
}
void Matrix::Input(){
cout<<"\n---行列数:";
cin>>n;
cout<<endl<<"输入行列式:"<<endl;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>A[i][j];
int j=0;
for(i=n;i<2*n;i++){
A[j][i]=1;
j++;
}
}
void Matrix::Cheak_IsSolvable(){
while(1){
if(Cal_DetA()){
cout<<"\n|A|="<<Det_A<<endl<<endl;
cout<<"(A|E)="<<endl;
Display(A,n,2*n);
break;
}
else{
cout<<"此矩阵的行列式为0,无解"<<endl;
Input();
}
}
}
void Matrix::Conversion(){
float temp[6][12];
for(int i=0;i<n;i++)//替身
for(int j=0;j<2*n;j++)
temp[i][j]=A[i][j];
LD_triangle(temp,n);//左下角变换0
Aii_Cto_1(temp,n); //对角变1
RU_triangle(temp,n);//右上角变换
Save_To_Result(temp,*this);
}
void LD_triangle(float temp[6][12],int n){
for(int i=0;i<n-1;i++){
if(temp[i][i]){//对角线元素不为0
if(temp[i][i]!=1.0)
if(int j=Find(temp,i,n)) Swap(temp,i,j,n);
for(int m=i+1;m<n;m++){
if(temp[m][i]){
float t=-(temp[m][i])/temp[i][i];
for(int p=0;p<2*n;p++){//R(m)+tRi
temp[m][p]=temp[m][p]+t*temp[i][p];
}
if(t>0)
cout<<"R"<<m+1<<"+"<<t<<"R"<<i+1<<":"<<endl;
else
cout<<"R"<<m+1<<t<<"R"<<i+1<<":"<<endl;
Display(temp,n,2*n);
}
else continue;
}
}
else {//若对角线元素为0
int m; for(m=i+1;m<n;m++){//
if(temp[m][i]){//使对角线元素非0
for(int p=0;p<n;p++)//Ri+Rm
temp[i][p]=temp[m][p]+temp[i][p];
break;
}
else continue;
}
if(m==n){ //可逆矩阵 不会出现此情况(对角元素为零,且此元素以下全为零)
//此情况 矩阵 行列式值为0
}
cout<<"R"<<i+1<<"+"<<"R"<<m+1<<endl;
Display(temp,n,2*n);
i--;
}
}
}
int Find(float temp[6][12],int i,int n){
for(int m=i+1;m<n;m++)
if(temp[m][i]==1.0)
return m;
return 0;
}
void Swap(float temp[6][12],int i,int j,int n){
cout<<"R"<<i+1<<"<-->R"<<j+1<<endl;
for(int m=0;m<2*n;m++){
temp[i][m]+=temp[j][m];
temp[j][m]=temp[i][m]-temp[j][m];
temp[i][m]-=temp[j][m];
}
Display(temp,n,2*n);
}
void Aii_Cto_1(float temp[6][12],int n){
for(int i=0;i<n;i++){
if(temp[i][i]!=1.0){
float t=1.0/temp[i][i];
cout<<"R"<<i+1<<"/"<<temp[i][i]<<endl;
for(int p=0;p<2*n;p++){//R(m)+tRi
temp[i][p]*=t;
}
Display(temp,n,2*n);
}
}
}
void RU_triangle(float temp[6][12],int n){
for(int i=n-1;i>0;i--){
for(int m=i-1;m>=0;m--){
if(temp[m][i]){
float t=-(temp[m][i])/(temp[i][i]);
for(int p=i;p<2*n;p++){ //R(m)+tempRi
temp[m][p]=temp[m][p]+t*temp[i][p];
}
if(t>0)
cout<<"R"<<m+1<<"+"<<t<<"R"<<i+1<<":"<<endl;
else
cout<<"R"<<m+1<<t<<"R"<<i+1<<":"<<endl;
Display(temp,n,2*n);
}
else continue;
}
}
}
void Display(float A[6][12],int m,int n){
for(int i=0;i<m;i++){
cout<<"|";
for(int j=0;j<n;j++){
cout<<setw(8)<<A[i][j];
if((j+1)%m==0)
cout<<" |";
}
cout<<endl;
}
cout<<endl;
}
void Save_To_Result(float temp[6][12],Matrix &D){
for(int i=0;i<D.n;i++)
for(int j=D.n;j<2*D.n;j++)
D.result[i][j-D.n]=temp[i][j];
}
bool Matrix::Cal_DetA(){
float temp[6][6];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
temp[i][j]=A[i][j];
for(i=0;i<n-1;i++){
if(temp[i][i]){//对角线元素不为0
for(int m=i+1;m<n;m++){
if(temp[m][i]){
float tem=-(temp[m][i])/temp[i][i];
for(int p=0;p<n;p++)//R(m)+tempRi
temp[m][p]=temp[m][p]+tem*temp[i][p];
}
else continue;
}
}
else {//若对角线元素为0
int m;
for(m=i+1;m<n;m++){//
if(temp[m][i]){//使对角线元素非0
for(int p=0;p<n;p++)//Ri+Rm
temp[i][p]=temp[m][p]+temp[i][p];
break;
}
else continue;
}
if(m==n){
Det_A=0;
return false;
}
i--;
}
}
Det_A=temp[0][0];//求对角积
for(i=1;i<n;i++)
Det_A=Det_A*temp[i][i];
if(Det_A) return true;
else return false;
}
void Matrix::Out_Result(){
cout<<"Result:"<<endl;
for(int i=0;i<n;i++){
cout<<"|";
for(int j=0;j<n;j++){
cout<<setw(8)<<result[i][j];
}
cout<<" |"<<endl;
}
cout<<endl;
}