數值計算——列主元高斯消去法求解線性方程組(附代碼)

目錄

列主元高斯消去法原理

列主元高斯消去法流程圖

C++程序源代碼

實例

運行結果


列主元高斯消去法原理

          在基本高斯消去法的消元過程中並沒有考慮任何數值方面的問題,事實上這方面的問題是常見的,也是不能忽略的,即當主元a_{kk}^{(k)}\neq 0,且a_{kk}^{(k)}很小時,高斯消去法雖然能執行下去,但用a_{kk}^{(k)}作爲主元計算行乘數時,會擴大誤差,導致結果不可靠,甚至嚴重失真

 基本高斯消去法的求解過程如下(具體原理參考https://blog.csdn.net/weixin_41788456/article/details/102485139):

設Ax=b,A \in R^{n\times n},若A的所有順序主子式均不爲零,則基本高斯消元無需換行進行到底,得到唯一解,其消元和回代的計算公式爲:

(1)消元計算     對於 k=1,2,\cdots ,n-1,

                                                               m_{ik}=\frac{a_{ik}^{(k)}}{a_{kk}^{(k)}} ,i=k+1,\cdots ,n,\quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad\quad \left (1 \right ) 

                                     a_{ij}^{(k+1)}=a_{ij}^{(k)}}-m_{ik}{a_{kj}^{(k)} ,b_{i}^{(k+1)}=b_{i}^{(k)}}-m_{ik}{b_{k}^{(k)} ,i=k+1,\cdots ,n.\quad\quad \quad\quad \quad\quad\quad \quad \quad\quad\quad \left (2 \right )

(2)回代計算

                                        x_{n}=\frac{b_{n}^{(n)}}{a_{nn}^{(n)}} ,x_{i}=\frac{b_{i}^{(i)}-\sum_{j=i+1}^{n}a_{ij}^{(i)}x_{j}}{a_{ii}^{(i)}},i=n-1,\cdots ,1.\quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \left (3 \right )

在上面的求解過程中可以看出,適當的改變算法可以有效的提高精度,其基本思想是,在高斯消去法的每一步先選擇一個絕對值最大的元素,在進行行行交換、消元,即變換到第k步時,從第k列的a_{kk}^{(k)}及以下的各元素中選出絕對值最大者,然後通過行變換將它交換到主元素a_{kk}^{(k)}的位置上,再用其消去主對線以下的其他元素,最後變爲同解的上三角形方程組,這種方法稱爲列主元高斯消去法。

列主元高斯消去法流程圖

C++程序源代碼

 

//列主元高斯消去法實現
//開發人員:chenshuai  開發日期:2019.11.24   郵箱:[email protected] 
#include "pch.h"
#include <iostream>//基本數據流輸入/輸出
#include <iomanip> //參數化輸入/輸出 
#include <vector>//STL動態數組容器
using namespace std;
//************************
//列主元高斯消去法公式
//***********************
vector<double> cpe_gaussian_elimination(vector<vector<double>>a, vector<double>b); //高斯消去法求解線性方程組AX=B
vector<double> cpe_gaussian_elimination(vector<vector<double>>a, vector<double>b)
{
	int n = size(b);
	vector<double>x;    //定義方程組解
	x.resize(n);
	vector<double>mi_k; //定義消去過程中的中間變量
	mi_k.resize(n);
	double sum,max=0,c;
	//n-1步消元
	for (int k = 0; k < n - 1; k++)
	{
		//列主元,找到絕對值最大的主元
		if (a[k][k] == 0 || fabs(a[k][k]) < epslion)//列主元的條件就是主元爲0或者主元小於某一個值
		{
		    max = fabs(a[k][k]);
			for (int i = k; i < n; i++)
			{
				if (max < fabs(a[i][k]))
				{
					max = fabs(a[i][k]);
				}
			}
			//交換該行
			for (int i = k; i < n; i++)
			{
				if (max == fabs(a[i][k]))
				{
					for (int j = k; j < n; j++)
					{
						c = a[k][j];
						a[k][j] = a[i][j];
						a[i][j] = c;
					}
					c = b[k];
					b[k] = b[i];
					b[i] = c;
				}
			}
		//求出第i次初等行變換系數
			for (int j = k + 1; j < n; j++)
			{
				mi_k[j] = a[j][k] / a[k][k];
			}
			for (int i = k + 1; i < n; i++)
			{
				for (int j = 0; j < n; j++)
				{
					a[i][j] = a[i][j] - mi_k[i] * a[k][j];
				}
				b[i] = b[i] - mi_k[i] * b[k];
			}
	}	//回代過程
	x[n - 1] = b[n - 1] / a[n - 1][n - 1];
	for (int i = n - 2; i >= 0; i--)
	{
		sum = 0;
		for (int j = i + 1; j < n; j++)
		{
			sum = sum + a[i][j] * x[j];
		}
		x[i] = (b[i] - sum) / a[i][i];
	}
	return x;
}
int main()
{
	int n = 2;
	vector<vector<double>>a;
	a.resize(n, vector<double>(n));
	vector<double>b(n);
	vector<double>x;
	a[0] = { 0.007,-0.8 }, a[1] = {-0.1 ,10};
	b = { 0.7,10};
	x = cpe_gaussian_elimination(a, b);
	cout << "解爲:" << endl;
	for (int i = 0; i < n; i++)
		cout <<"x["<<i<<"]="<< fixed << setprecision(2) << setw(5) << x[i] << endl;
}

實例

用列主元高斯消去法求解線性方程組:

                                                               \left\{\begin{matrix} 0.007x_{1}-0.8x_{2}=0.7\\ -0.1x_{1}+10x_{2}=10 \end{matrix}\right.\quad\quad \quad\quad \quad\quad \quad\quad \quad\quad\quad \quad\quad \quad\quad \quad\quad\quad \quad \quad\quad \left (4 \right )

運行結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章