Gauss 消元法求解线性方程组
内容
消元法是将方程组中的一方程的未知数用含有另一未知数的代数式表示,并将其代入到另一方程中,这就消去了一未知数,得到一解;或将方程组中的一方程倍乘某个常数加到另外一方程中去,也可达到消去一未知数的目的。消元法主要用于二元一次方程组的求解。
核心
1)两方程互换,解不变;
2)一方程乘以非零数k,解不变;
3)一方程乘以数k加上另一方程,解不变 [2] 。
举例: 有这样一个简单的例子:
x1 + 2x2 = 5;
2x1 + 3*x2 = 8
其解为 x1=1;x2=2;
代码实现:
#include <iostream>
#include<string.h>
#include<math.h>
using namespace std;
const int MAXN=30;
const double EPS=10e-8;
double a[MAXN][MAXN];//存储方程组对应矩阵
bool l[MAXN];//是否为自由元
int start[MAXN]; //开始状态
int endss[MAXN]; //结束状态
//高斯消元模板
inline int solve(const int &n)
{
int res=0,r=0;
for(int i=0; i<n; ++i) l[i]=false;
for(int i=0; i<n+1; ++i)
{
for(int j=r; j<n; ++j)
{
if(fabs(a[j][i])>EPS)
{
for(int k=i; k<=n; ++k)
swap(a[j][k],a[r][k]);
break;
}
}
if(fabs(a[r][i])<EPS)
{
++res;
continue;
}
for(int j=0; j<n; ++j)
{
if(j!=r&&fabs(a[j][i])>EPS)
{
double tmp=a[j][i]/a[r][i];
for(int k=i; k<=n; ++k)
a[j][k]-=tmp*a[r][k];
}
}
l[i]=true,++r;
cout << endl;
for (int i = 0; i<n; i++) {
for (int j = 0; j<n+1; j++) {
cout.width(4);
cout << a[i][j] << " ";
}
cout << endl;
}
}
return res;
}
//模板结束
bool issolve(const int&n){
//判断是否存在无解
for(int i=0; i<n-1; i++)
{
bool flag=true;
for(int j=0;j<n-1;j++){
if(a[i][j]!=0){
flag=false;
continue;
}
}
if(flag&&a[i][n-1]!=0) return false;
}
return true;
}
void result(const int&n) {
int cols = n+1;
int rows = n;
double ans[100] = {0};
double sum = 0;
for (int i = 1; i < cols; i++) {
sum = a[cols - 1- i][cols -1 ];
for (int j = 1; j < i; j++) {
sum -= ans[cols - j] * a[rows - i][rows - j];
}
ans[cols - i] = sum / a[cols-1 - i][cols - 1 - i];
}
for (int i = 1; i < cols; i++) {
cout << ans[i] << " ";
}
}
int main()
{
int n = 2; //方程组的个数
//求解方程组
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 5;
a[1][0] = 2;
a[1][1] = 3;
a[1][2] = 8;
//输出
for (int i = 0; i<n+1; i++) {
for (int j = 0; j<n+2; j++) {
cout.width(4);
cout << a[i][j] << " ";
}
cout << endl;
}
//求解过程
int ans=solve(n);
if(!issolve(n-1))
{
cout<<"Oh,it's impossible~!!"<<endl;
}
else
{
cout<<(1<<(ans-1))<<endl; //输出解的个数
result(n); //求解
}
return 0;
}