ヤコビ・ガウス反復法の原理とその実際の使用例 (C++ コード付き)

原理紹介

       ヤコビ反復法とガウス反復法は主に線形方程式を解くために使用され、n 回の反復後に正確な値に収束して近似解を解くという目的を達成します。

ヤコビ反復法とガウス反復法の違い

ヤコビアン反復法

        ヤコビアン反復法の反復原理は、次の方程式のように、各反復で前の反復の値を使用することです。

\large \left\{ {\begin{array}{*{20}{c}} { {a_{11}}{x_1} + {a_{12}}{x_2} + ...{a_{1n }}{x_n} = {b_1}}\\ { {a_{21}}{x_1} + {a_{22}}{x_2} + ...{a_{2n}}{x_n} = {b_2} }\\ {......}\\ { {a_{n1}}{x_1} + {a_{n2}}{x_2} + ...{a_{nn}}{x_n} = { b_n}} \end{配列}} \正しい。\

 変換して取得できます

\large {x_1^{(k + 1)} = \frac{1}{ { {a_{11}}}}\left( { {b_1} - {a_{11}}x_1^{(k )} - {a_{12}}x_2^{(k)} - ... - {a_{1n}}x_n^{(k)}} \right)}

\large {x_2^{(k + 1)} = \frac{1}{ { {a_{22}}}}\left( { {b_2} - {a_{21}}x_1^{(k )} - {a_{22}}x_2^{(k)} - ... - {a_{2n}}x_n^{(k)}} \right)}

\大きい {......}

\large {x_1^{(k + 1)} = \frac{1}{ { {a_{n1}}}}\left( { {b_n} - {a_{n1}}x_1^{(k )} - {a_{n2}}x_2^{(k)} - ... - {a_{nn}}x_n^{(k)}} \right)}

要約した式は次のとおりです。

\large {\rm{x}}_i^{(k + 1)} = \frac{1}{ { {a_{ii}}}}\left( { {b_i} - \sum\limits_{ \begin{array}{*{20}{c}} {j = 1}\\ {j \ne i} \end{array}}^n { {a_{ij}}x_i^{(k)} \right),i = 1,2,...n

 

 ガウス反復法

       ガウス反復法はヤコビアンよりも高速です。ガウス反復法では、各反復プロセスの結果を反復プロセスに取り込むという原理が使用されます。

ヤコビアン アルゴリズムは最適化されており、具体的なプロセスは次のとおりです。

\large {x_1^{(k + 1)} = \frac{1}{ { {a_{11}}}}\left( { {b_1} - {a_{11}}x_1^{(k + 1)} - {a_{12}}x_2^{(k + 1)} - ... - {a_{1n}}x_n^{(k + 1)}} \right)}

\large {x_2^{(k + 1)} = \frac{1}{ { {a_{22}}}}\left( { {b_2} - {a_{21}}x_1^{(k + 1)} - {a_{22}}x_2^{(k + 1)} - ... - {a_{2n}}x_n^{(k + 1)}} \right)}

\大きい {......}

\large {x_1^{(k + 1)} = \frac{1}{ { {a_{n1}}}}\left( { {b_n} - {a_{n1}}x_1^{(k + 1)} - {a_{n2}}x_2^{(k + 1)} - ... - {a_{nn}}x_n^{(k + 1)}} \right)}

要約した式は次のとおりです。

\large x_{ii}^{(x+1)}= \frac{1}{ { {a_{ii}}}}\left( { {b_i} - \sum\limits_{j = 0} ^{i - 1} {{a_{ij}}x_j^{(k + 1)}} - \sum\limits_{j = i + 1}^n {{a_{ij}}x_j^{( k)}} } \right),i = 1,2,...n\

 添付の C++ コード

//雅可比迭代法
//4x + 2x + x = 11    (x1 ,x2, x3)   范例
//x + 4x + 2x = 18
//2x + x + 5x = 22
//  " * "为参数数量更改需要更改处
#include<iostream>
#include<cmath>
#define a   3   //*定义系数个数,这里设置为3    
#define b   3   //*一个公式3个系数(a),一共3个式子
using namespace std;

double A[a][b] = { 4,2,1 , 1,4,2 , 2,1,5 };         //*系数矩阵
double B[b] = {11,18,22};            //*行列式矩阵
double e = pow(10, -7);      //定义精度
double C[b][a + 1];          //记录迭代矩阵
double x0[a] = { 0 };                 //初始迭代矩阵
double X[a];             //用来储存第K次迭代后的数值

bool Judge(double x1, double x2, double x3)   //*判断精度(本题共有3个系数,所以三个变量,题目改变增加变量)
{
	int m = 0; 
	if (abs(x0[0] - x1) < e) m++;            //*(更改系数个数)
	if (abs(x0[1] - x2) < e) m++;
	if (abs(x0[2] - x3) < e) m++; 
	
	if (m == 3)   return 1;
	else return 0;
}

void output(double X[])
{
	int i;
	for (int i = 0; i < a; i++)
	{
		printf("%.5f", X[i]);
		cout << " ";
	}
	cout << endl;
}
void Matrix()             //计算迭代公式中的系数矩阵
{
	for (int i = 0; i < a; i++)
	{
		for (int j = 0; j < a; j++)
		{
			C[i][j] = -(A[i][j] / A[i][i]);
			if (i == j)
			{
				C[i][j] = 0;
			}
		}
		C[i][3] = B[i] / A[i][i];       //*(因为系数有三个,所以第i行第四个元素存放第i个式子的数值)
	}
	
	
}

void J()   //雅可比
{
	int n = 0;               //迭代次数
	//double X[a];             //用来储存第K次迭代后的数值
	for (int i = 0; i < a; i++)   
	{
		X[i] = x0[i];
	}
	while (true)
	{
		for (int i = 0; i < a; i++)
		{
			x0[i] = C[i][0] * X[0] + C[i][1] * X[1] + C[i][2] * X[2]+C[i][3];     //*
		}
		n++;
		if (Judge(X[0], X[1], X[2]))
		{
			break;
		}
			
		cout << "第" << n << "次迭代结果" << endl;
		output(X);             //打印第i次迭代结果
		for (int i = 0; i < a; i++)
		{
			X[i] = x0[i];
		}
	}
}

void main()
{
	Matrix();
	cout << "雅可比迭代" << endl;
	J();
	cout << "最终结果" << endl;
	output(X);
}
//高斯迭代法
//4x + 2x + x = 11    (x1 ,x2, x3)   范例
//x + 4x + 2x = 18
//2x + x + 5x = 22
//  " * "为参数数量更改需要更改处
#include<iostream>
#include<cmath>
#define a   3   //*定义系数个数,这里设置为3    
#define b   3   //*一个公式3个系数(a),一共3个式子
using namespace std;

double A[a][b] = { 4, 2, 1, 1, 4, 2, 2, 1, 5 };         //*系数矩阵
double B[b] = { 11, 18, 22 };            //*行列式矩阵
double e = pow(10, -7);      //定义精度
double C[b][a + 1];          //记录迭代矩阵
double x0[a] = { 0 };                 //初始迭代矩阵
double X[a];             //用来储存第K次迭代后的数值

bool Judge(double x1, double x2, double x3)   //*判断精度(本题共有3个系数,所以三个变量,题目改变增加变量)
{
	int m = 0;
	if (abs(x0[0] - x1) < e) m++;            //*(更改系数个数)
	if (abs(x0[1] - x2) < e) m++;
	if (abs(x0[2] - x3) < e) m++;

	if (m == 3)   return 1;
	else return 0;
}

void output(double X[])
{
	int i;
	for (int i = 0; i < a; i++)
	{
		printf("%.5f", X[i]);
		cout << " ";
	}
	cout << endl;
}
void Matrix()             //计算迭代公式中的系数矩阵
{
	for (int i = 0; i < a; i++)
	{
		for (int j = 0; j < a; j++)
		{
			C[i][j] = -(A[i][j] / A[i][i]);
			if (i == j)
			{
				C[i][j] = 0;
			}
		}
		C[i][3] = B[i] / A[i][i];       //*(因为系数有三个,所以第i行第四个元素存放第i个式子的数值)
	}


}

void GS()   //高斯
{
	int n = 0;               //迭代次数
	for (int i = 0; i < a; i++)
	{
		X[i] = x0[i];
	}
	while (true)
	{
		for (int i = 0; i < a; i++)
		{
			x0[i] = C[i][0] * x0[0] + C[i][1] * x0[1] + C[i][2] * x0[2] + C[i][3];     //*(x0初始矩阵变为k+1次迭代结果)
		}
		n++;
		if (Judge(X[0], X[1], X[2]))
		{
			break;
		}

		cout << "第" << n << "次迭代结果" << endl;
		output(x0);             //打印第i次迭代结果
		for (int i = 0; i < a; i++)
		{
			X[i] = x0[i];
		}
	}
}

void main()
{
	Matrix();
	cout << "高斯迭代" << endl;
	GS();
	cout << "最终结果" << endl;
	output(x0);
}

ヤコビ反復法とガウス結果の比較

上の例では、ヤコビ法を 50 回実行して 10^(-7) の精度で近似解を取得します。ガウス反復法では 17 回実行すると 10^(-7) の精度で近似解を取得できます。 Gauss-Se デル反復法の効率は、ヤコビアン反復法の効率よりもはるかに優れています。

おすすめ

転載: blog.csdn.net/qq_60811855/article/details/125876111