目錄
列主元高斯消去法原理
在基本高斯消去法的消元過程中並沒有考慮任何數值方面的問題,事實上這方面的問題是常見的,也是不能忽略的,即當主元,且很小時,高斯消去法雖然能執行下去,但用作爲主元計算行乘數時,會擴大誤差,導致結果不可靠,甚至嚴重失真。
基本高斯消去法的求解過程如下(具體原理參考https://blog.csdn.net/weixin_41788456/article/details/102485139):
設Ax=b,,若A的所有順序主子式均不爲零,則基本高斯消元無需換行進行到底,得到唯一解,其消元和回代的計算公式爲:
(1)消元計算 對於
(2)回代計算
在上面的求解過程中可以看出,適當的改變算法可以有效的提高精度,其基本思想是,在高斯消去法的每一步先選擇一個絕對值最大的元素,在進行行行交換、消元,即變換到第k步時,從第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;
}
實例
用列主元高斯消去法求解線性方程組: