高斯消去法解线性方程组C++实现

       一.问题分析:高斯消去法解线性方程组主要面对的问题是矩阵的运算,所以可以定义一个矩阵类Matrix类作为基类,然后由矩阵类Matrix类派生出一个线性方程组类LinearEqu类。

       二.矩阵功能分析:(1)Matrix类处理n*n的方阵,方阵用一个一维数组存放,矩阵类Matrix的数据成员包括数组的首地址和矩阵长度n,函数成员有设置矩阵的值setMatrix()和显示矩阵printMatrix()。(2)LinearEqu类除了由矩阵Matrix继承过来的存放矩阵A的成员之外,还包括存放解向量X和方程右端向量b的数组的首地址。LinearEqu类的主要操作有方程组设置setLinearEqu(),显示printLinearEqu(),求解solve()及输出方程组的解printSolution()

注:Matrix类只对矩阵进行处理,不掺杂任何方程思想,LinearEqu类利用矩阵类来求解方程

       三.画出UML图

                          

         四.代码

             Matrix.h文件

#ifndef _MATRIX_H_
#define _MATRIX_H_
class Matrix{
public:
	Matrix(int size = 2);
	~Matrix();
	void setMatrix(const double* values);//矩阵赋初值
	void printMatrix() const;//显示矩阵
	int getSize() const{ return size; }//得到矩阵大小
	double &element(int i, int j){ return elements[i*size + j]; }
	double element(int i, int j) const{ return elements[i*size + j]; }//取矩阵的第i行第j列的元素
private:
	int size;
	double* elements;//矩阵存放数组首地址
};
#endif

 Matrix.cpp文件,实现Matrix.h中声明的函数 

#include"Matrix.h"
#include<iostream>
using namespace std;

Matrix::Matrix(int size /*= 2*/) :size(size){//Matrix类的构造函数的实现
	elements = new double[size*size];//动态内存分配
}

Matrix::~Matrix(){//矩阵Matrix的析构函数
	delete[] elements;//内存释放
}

void Matrix::setMatrix(const double* values){//矩阵赋初值
	for (int i = 0; i < size*size; i++)
		elements[i] = values[i];
}

void Matrix::printMatrix() const{//显示矩阵
	cout << "The Matrix is:" << endl;
	for (int i = 0; i < size; i++){
		for (int j = 0; j < size; j++)
			cout << element(i, j) << " ";
		cout << endl;
	}
}

 LinearEqu.h文件

#ifndef _LINEAREQU_H_
#define _LINEAREQU_H_
#include"Matrix.h"
class LinearEqu :public Matrix{
public:
	LinearEqu(int size = 2);
	~LinearEqu();
	void setLinearEqu(const double* a, const double* b);//方程赋值(设置线性方程组)
	//a表示的是系数矩阵,b表示的是右端矩阵
	bool solve();//全选主元高斯消去法求解方程
	void printLinearEqu() const;//显示方程
	void printSolution() const;//显示方程的解
private:
	double* sums;//方程右端向量
	double* solution;//方程的解
};
#endif

 LinearEqu.cpp文件,实现LinearEqu.h中声明的函数 

#include"LinearEqu.h"
#include<iostream>
#include<cmath>
using namespace std;

//用size调用基类构造函数
LinearEqu::LinearEqu(int size/*=2*/) :Matrix(size) {
	sums = new double[size];//动态内存分配
	solution = new double[size];
}

LinearEqu::~LinearEqu(){
	delete[] sums;
	delete[] solution;
}

//设置线性方程组
void LinearEqu::setLinearEqu(const double* a, const double* b){
	setMatrix(a);//调用基类函数
	for (int i = 0; i < getSize(); i++)
		sums[i] = b[i];
}

//显示线性方程组
void LinearEqu::printLinearEqu() const{
	cout << "The Line eqution is:" << endl;
	for (int i = 0; i < getSize(); i++){
		for (int j = 0; j < getSize(); j++)
			cout << element(i, j) << " ";
		cout << "     " << sums[i] << endl;
	}
	cout << endl;
}

//输出方程的解
void LinearEqu::printSolution() const{
	cout << "The Result eqution is:" << endl;
	for (int i = 0; i < getSize(); i++)
		cout << "x[" << i << "]=" << solution[i] << endl;
}

//交换两个实数
inline void swap(double &v1, double &v2){
	double temp = v1;
	v1 = v2;
	v2 = temp;
}

bool LinearEqu::solve(){//全选主元素高斯消去法求解方程
	int *js = new int[getSize()];//存储主元素所在列号的数组

	//选主元素
	for (int k = 0; k < getSize()-1; k++){
		int is;//主元素所在行号
		double max = 0;//所有元素的最大值
		for (int i = k; i < getSize(); i++){
			for (int j = k; j < getSize(); j++){
				double t = fabs(element(i, j));
				if (t > max){
					max = t;
					js[k] = j;
					is = i;
				}
			}
		}
		if (max == 0){
			delete[] js;
			return false;
		}
		else{
			//通过行列交换,把主元素交换到第k行第k列上
			if (js[k] != k)//主元素不在第k列上,交换一列
				for (int i = 0; i < getSize(); i++)
					swap(element(i, k), element(i, js[k]));
			if (is != k){//主元素不在第k行上,交换一行
				for (int j = k; j < getSize(); j++){
					swap(element(is, j), element(k, j));
					swap(sums[k], sums[is]);
				}
			}
		}

		//消去过程
		double major = element(k, k);
		for (int j = k + 1; j < getSize(); j++)
			element(k, j) /= major;
		sums[k] /= major;
		for (int i = k + 1; i < getSize(); i++){
			for (int j = k + 1; j < getSize(); j++)
				element(i, j) -= element(i, k)*element(k, j);//行之间的操作
			sums[i] -= element(i, k)*sums[k];
		}
	}
	//判断剩下的一个元素是否等于0(等于0则矩阵的秩不等于矩阵的行数,则无解)
	double d = element(getSize() - 1, getSize() - 1);
	if (fabs(d) < 1e-15){
		delete[] js;
		return false;
	}

	//求出解之前验证一下最终化简结果
	printMatrix();
	cout << "Output right end matrix:" << endl;
	for (int i = 0; i < getSize(); i++)
		cout << sums[i] << " ";
	cout << endl << endl;

	//回代过程
	solution[getSize() - 1] = sums[getSize() - 1] / d;
	for (int i = getSize() - 2; i >= 0; i--){
		double t = 0.0;
		for (int j = i + 1; j <= getSize() - 1; j++)
			t += element(i, j)*solution[j];//实际上不是单位矩阵
		solution[i] = sums[i] - t;
	}
	js[getSize() - 1] = getSize() - 1;//最后一行最后一列主元素就是本列
	for (int k = getSize() - 1; k >= 0; k--)
		if (js[k] != k) swap(solution[k], solution[js[k]]);
	delete[] js;
	return true;
}

主函数文件

#include<iostream>
#include"LinearEqu.h"
using namespace std;
int main(){
	double a[] = {//方程系数矩阵
		0.2368, 0.2471, 0.2568, 1.2671,
		0.1968, 0.2071, 1.2168, 0.2271,
		0.1581, 1.1675, 0.1768, 0.1871,
		1.1161, 0.1254, 0.1397, 0.1490
	};
	double b[] = { 1.8471, 1.7471, 1.6471, 1.5471 };//方程右端项
	LinearEqu equ(4);//定义一个四元方程组对象
	equ.setLinearEqu(a, b);//设置方程组
	equ.printLinearEqu();//输出方程组
	if (equ.solve())
		equ.printSolution();
	else
		cout << "Fail" << endl;
	return 0;
}

五. 结果

六,分析

其实该方法并不是我们平常手算矩阵解方程组的思路,这个是按照高斯消去法的逻辑将方程组矩阵一步步的转化,但是最后并没有转化为单位矩阵,而是转化为了逻辑上的阶梯矩阵,然后进一步求出解,图中红色即为最终化成的矩阵

猜你喜欢

转载自blog.csdn.net/Dear_Jia/article/details/84721418