都不知道有多少时间没写blog了,不是不想写啊~~~主要是想如果要写东西的话,这段时间真没什么好写的,不是考试就是很多烦心的事,偶尔在
豆瓣上写一些关于自己的心情之类的,哎~~~~最近看到我朋友做了一个解方程组的program ,不过他是用flex 写的,是一个flash~~个人觉得很有意思,所以就想自己也写一个。其他的也不怎么想就想想了解 一下高斯消去法是什么???后来才发现这个方法其实在我平时做线性代数的时候经常用到(后来我发现那个方法是我就是我那个同学教我的),呵呵,主要想把他变成用C++写的,所以就去很仔细的了解了一下高斯消去法。
那我就先讲一下什么是高斯消去法吧?
设有方程组Ax=b,设A是可逆矩阵。高斯消去法的基本思想就是僵局真的初等行变换作用于方程组的增广矩阵B=[A,b],将其中的A变换成一个上三角矩阵,然后求解这个三角形方程组。
上面的这个解题的方式如果是学过线性代数的都应该是看的懂的,如果真的不知道的话那就去看看线性代数的关于矩阵的这一章吧。
下面我们讲一下他的解题思路:
关键是要关于增光矩阵B怎么把A换成上三角形(我们这里假设A是n*n的矩阵),所以B的规格是n*(n+1)
//郁闷死了~~~~~怎么插入一个图片那么难的啊~~~~~
既然不能看图片那我就不介绍这个算法的数学形式了,下面是我用C++写的算法实现(写的不怎么好,不过还是可以运行的)
#include <iostream>
#include<iomanip.h>
using namespace std;
int change_num=0;
void display(double **l_array,int r_size1,int r_size2) //这个函数是用来显示矩阵(主要是用来调试使用的)
{
for(int i=0; i<r_size1; i++)
for(int j=0; j<r_size2; j++)
{
if(j!=0)
{
cout<<setprecision(4)<<setiosflags(ios_base::left)<<setw(7)<<l_array[i][j];
}
else
{
cout<<setprecision(4)<<setiosflags(ios_base::left)<<l_array[i][j]<<" ";
}
if(j+1==r_size2)
{
cout<<endl;
}
}
cout<<resetiosflags(ios_base::left);
}
//这个下面的是算出上三角形
bool Change(double **&array,int r_size,int c_size)
{
int k=0;
double max=array[k][k];
int num=0;
bool flag=false;
while(k<r_size) //k表示现在在哪一行
{
max=array[k][k];
for(int i=k; i<r_size; i++)
{
if(array[i][k]>max)
{
flag=true;
max=array[i][k];
num=i; //num表示最大行的行数
}
}
if(!flag)
{
num=k;
}
if(max==0) //如果一个列中的最大数是0的话那就说明这个矩阵的奇异矩阵
{
return false;
}
else if(k!=num)
{
double temp=0;
for(int i=0; i<c_size; i++)
{
temp=array[k][i];
array[k][i]=array[num][i];
array[num][i]=temp;
change_num++;
}
}
for(int i=k; i<r_size-1; i++)
{
double temp=array[i+1][k]; //这里的temp一定要保存的,因为直接使用array[i+1][k],在下面的计算中会改变
for(int j=k; j<c_size; j++)
{
array[i+1][j]-=((temp/array[k][k])*array[k][j]);
}
}
k++;
flag=false;
}
return true;
}
double Rowlay(double **&array,int r_size, int c_size ) // 求行列式
{
double sum=1;
for(int i=0; i<r_size; i++)
{
sum*=array[i][i];
}
return sum;
}
void Equation(double **&array,int r_size, int c_size) //求方程组解
{
for(int i=0; i<r_size; i++)
{
double temp1=array[i][i];
for(int j=i; j<c_size; j++)
{
array[i][j]/=temp1;
}
}
for(int i=1; i<r_size; i++)
{
for(int j=i-1; j>=0; j--)
{
double temp2=array[j][i];
for(int h=i; h<c_size; h++)
{
array[j][h]-=(temp2*array[i][h]);
}
}
}
}
int main()
{
int count=0;
cin>>count;
double **array=new double*[count];
for(int i=0; i<count; i++)
{
array[i]=new double[count+1];
}
for(int i=0; i<count; i++)
for(int j=0; j<count+1; j++)
{
cin>>array[i][j];
}
bool flag=Change(array,count,count+1);
if(flag)
{
cout<<endl;
double value=Rowlay(array,count,count+1);
if(change_num%2==1)
{
value*=-1;
}
cout<<"行列式为 "<<value<<endl;
Equation(array,count,count+1);
cout<<"方程解为"<<endl;
for(int i=0; i<count; i++)
{
char ch='x'+i;
cout<<ch<<"= "<<array[i][count]<<endl;
}
display(array,count,count+1);
}
else
{
cout<<"这个矩阵是奇异矩阵"<<endl;
cout<<"这个方程无数解!!!"<<endl;
cout<<"行列式为 "<<0<<endl;
}
for(int j=0; j<count; j++)
{
delete array[j];
}
delete []array;
}
这个是核心算法,不过真正实现出来是使用了java ,在写的过程中发现java不能使用指针,这让我困惑了一段时候,哎~~~~要不是因为课程要使用java,我想我也不会使用java,关于java的程序已经有点小功能了~~~~~~我上传到~~~~http://www.rayfile.com/zh-cn/files/18cef568-fc10-11de-b00d-0014221b798a/
大家有兴趣可以看看~~~~~~~