Princípio do método de iteração de Jacobi-Gauss e exemplos de seu uso prático (com código C++)

Introdução do princípio

       O método de iteração de Jacobi e o método de iteração gaussiana são usados ​​principalmente para resolver equações lineares e, após n iterações, eles convergem para um valor exato para atingir o objetivo de resolver uma solução aproximada

A diferença entre o método de iteração de Jacobi e o método de iteração gaussiana

método iterativo jacobiano

        O princípio de iteração do método de iteração Jacobiana é que cada iteração usa o valor da iteração anterior , como as seguintes equações

\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{array}} \right.\

 pode ser obtido pela transformação

\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)}

\grande {......}

\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)}

A fórmula resumida é:

\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

 

 Método iterativo gaussiano

       O método iterativo gaussiano é mais rápido que o jacobiano.O método iterativo gaussiano usa o princípio de trazer os resultados de cada processo iterativo para dentro do processo iterativo.

O algoritmo jacobiano é otimizado e o processo específico é o seguinte:

\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)}

\grande {......}

\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)}

A fórmula resumida é:

\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ódigo C++ anexado

//雅可比迭代法
//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);
}

Comparação do Método Iterativo de Jacobi e Resultados Gaussianos

No exemplo acima, o jacobiano executa 50 vezes para obter uma solução aproximada com uma precisão de 10^(-7), e o método de iteração gaussiana pode obter uma solução aproximada com uma precisão de 10^(-7) após 17 vezes, então o Gauss-Se A eficiência do método Del iterativo é muito maior do que a do método iterativo Jacobiano.

Acho que você gosta

Origin blog.csdn.net/qq_60811855/article/details/125876111
Recomendado
Clasificación