求解線性方程組時,我們經常用的方法是高斯消去法,矩陣三角分解,雅克比迭代,以及迭代方法如共軛梯度等。在使用這些方法求解的過程中,通常需要,但是難免會遇到對角線有一些數爲0的情況。本文求解方法大致求解思路還是採取高斯消去法,在高斯消去法的基礎上多了一個矩陣係數對角線爲0的判斷,如果爲0,則與上一行交換,包括列向量對應的位置。
原理參考我之前寫的文章:https://blog.csdn.net/weixin_41788456/article/details/102485139
程序:
//開發人員:陳帥 開發日期:2019.10.15 郵箱:[email protected]
#include "pch.h"
#include <iostream>//基本數據流輸入/輸出
#include <iomanip> //參數化輸入/輸出
#include <vector>//STL動態數組容器
using namespace std;
//************************
//改進的高斯消去法公式
//***********************
vector<double> gaussian_elim_mutate(vector<vector<double>>a, vector<double>b); //高斯消去法求解線性方程組AX=B
vector<double> gaussian_elim_mutate(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;
double line_exchange = 0;
double m[3];
//如果對角線爲0,則交換上一行,直到不爲0爲止
for (int k = 0; line_exchange != -1; k++)
{
for (int i = 0; i < n; i++)
{
line_exchange = -1;
if (a[i][i] == 0)
{
line_exchange = i;
if (i == 0)
{
for (int j = 0; j < 3; j++)
{
m[j] = a[n - 1][j];
a[n - 1][j] = a[i][j];
a[i][j] = m[j];
}
m[0] = b[n - 1];
b[n - 1] = b[i];
b[i] = m[0];
}
else
{
for (int j = 0; j < 3; j++)
{
m[j] = a[i - 1][j];
a[i - 1][j] = a[i][j];
a[i][j] = m[j];
}
m[0] = b[i - 1];
b[i - 1] = b[i];
b[i] = m[0];
}
}
}
}
//再次判斷能否用高斯消去法(驗證)
for (int i = 0; i < n; i++)
{
if (a[i][i] == 0)
{
cout << "can't use Gaussian meathod" << endl;
}
}
//n-1步消元
for (int k = 0; k < n - 1; k++)
{
//求出第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()
{
vector<vector<double>>a;
a.resize(3, vector<double>(3));
vector<double>b(3);
vector<double>x;
a[0] = { 0,1.1,3.1 }, a[1] = { 2.0,0,0.36 }, a[2] = { 5.0,0.96,0 };
b = { 6.0,0.02,0.96 };
x = gaussian_elim_mutate(a, b);
cout << "解爲:" << endl;
for (int i = 0; i < 3; i++)
cout <<"x["<<i<<"]="<< fixed << setprecision(2) << setw(5) << x[i] << endl;
}
運行結果: