解方程组
{ 10 x 1 − x 2 − 2 x 3 = 7.2 − x 1 + 10 x 2 − 2 x 3 = 8.3 − x 1 − x 2 + 5 x 3 = 4.2 (1) \begin{cases} 10x_{1}-x_{2}-2x_{3}=7.2\\ -x_{1}+10x_{2}-2x_{3}=8.3\\ -x_{1}-x_{2}+5x_{3}=4.2 \end{cases}\tag1 ⎩ ⎨ ⎧10x1−x2−2x3=7.2−x1+10x2−2x3=8.3−x1−x2+5x3=4.2(1)
从方程组(1)的三个方程中分离出 x 1 , x 2 x_{1},x_{2} x1,x2 和 x 3 x_{3} x3:
{ x 1 = 0.1 x 2 + 0.2 x 3 + 0.72 x 2 = 0.1 x 1 + 0.2 x 3 + 0.83 x 3 = 0.2 x 1 + 0.2 x 2 + 0.84 (2) \begin{cases} x_{1}=0.1x_{2}+0.2x_{3}+0.72\\ x_{2}=0.1x_{1}+0.2x_{3}+0.83\\ x_{3}=0.2x_{1}+0.2x_{2}+0.84 \end{cases}\tag2 ⎩ ⎨ ⎧x1=0.1x2+0.2x3+0.72x2=0.1x1+0.2x3+0.83x3=0.2x1+0.2x2+0.84(2)
据此可建立迭代公式
{ x 1 ( k + 1 ) = 0.1 x 2 ( k ) + 0.2 x 3 ( k ) + 0.72 x 2 ( k + 1 ) = 0.1 x 1 ( k ) + 0.2 x 3 ( k ) + 0.83 x 3 ( k + 1 ) = 0.2 x 1 ( k ) + 0.2 x 2 ( k ) + 0.84 (3) \begin{cases} x_{1}^{(k+1)}=0.1x_{2}^{(k)}+0.2x_{3}^{(k)}+0.72\\ x_{2}^{(k+1)}=0.1x_{1}^{(k)}+0.2x_{3}^{(k)}+0.83\\ x_{3}^{(k+1)}=0.2x_{1}^{(k)}+0.2x_{2}^{(k)}+0.84 \end{cases}\tag3 ⎩ ⎨ ⎧x1(k+1)=0.1x2(k)+0.2x3(k)+0.72x2(k+1)=0.1x1(k)+0.2x3(k)+0.83x3(k+1)=0.2x1(k)+0.2x2(k)+0.84(3)
设取迭代初值 x 1 ( 0 ) = x 2 ( 0 ) = x 3 ( 0 ) = 0 x_{1}^{(0)}=x_{2}^{(0)}=x_{3}^{(0)}=0 x1(0)=x2(0)=x3(0)=0,下表记录了式(3)的迭代结果。从表中可以看出,当迭代次数 k 增大时,迭代值 x 1 ( k ) , x 2 ( k ) , x 3 ( k ) x_{1}^{(k)}, x_{2}^{(k)}, x_{3}^{(k)} x1(k),x2(k),x3(k) 会越来越逼近方程组(1)的精确解 x 1 ( ∗ ) = 1.1 x_{1}^{(*)}=1.1 x1(∗)=1.1, x 2 ( ∗ ) = 1.2 x_{2}^{(*)}=1.2 x2(∗)=1.2, x 3 ( ∗ ) = 1.3 x_{3}^{(*)}=1.3 x3(∗)=1.3。
k | x1(k) | x2(k) | x3(k) |
---|---|---|---|
0 | 0.00000 | 0.00000 | 0.00000 |
1 | 0.72000 | 0.83000 | 0.84000 |
2 | 0.97100 | 1.07000 | 1.15000 |
3 | 0.05700 | 1.15710 | 1.24820 |
4 | 1.08535 | 1.18534 | 1.28282 |
5 | 1.09510 | 1.19510 | 1.29414 |
6 | 1.09834 | 1.19834 | 1.29804 |
7 | 1.09944 | 1.19944 | 1.29934 |
8 | 1.09981 | 1.19981 | 1.29978 |
9 | 1.09994 | 1.19994 | 1.29992 |
运行示例:
程序源码:
#include <iostream>
#include <iomanip>
#define MAX 10
using namespace std;
int main(void)
{
int row;
cout << "请输入增广矩阵行数:";
cin >> row;
int col;
cout << "请输入增广矩阵列数:";
cin >> col;
double a[MAX][MAX];
for (int i = 1; i <= row; i++)
{
cout << "请输入增广矩阵第 " << i << " 行的元素:";
for (int j = 1; j <= col; j++)
{
cin >> a[i][j];
}
}
// 对增广矩阵元素进行处理化简
for (int i = 1; i <= row; i++)
{
for (int j = 1; j <= col; j++)
{
if (i != j && j != col)
{
// 非行列坐标相等的元素除以负行列坐标相等的元素
a[i][j] /= -a[i][i];
}
if (j == col)
{
// 常数项除以行列相等的元素
a[i][j] /= a[i][i];
}
}
}
// 将矩阵主对角线上的元素赋值为 0
for (int i = 1; i <= row; i++)
{
a[i][i] = 0;
}
double b[MAX];
cout << "请输入迭代初值:";
for (int i = 1; i < col; i++)
{
cin >> b[i];
}
int N;
cout << "请输入最大迭代次数:";
cin >> N;
double c[MAX];
for (int i = 1; i <= N; i++)
{
cout << "第 " << i << " 次迭代:";
// 用 count 控制迭代值按每行 col-1 个输出,即自变量个数输出
int count = 1;
// 每一次迭代 (i),求取每一行的行列坐标相等的值即 a[j][j]
for (int j = 1; j <= row; j++)
{
double item;
// j 循环 col 次,求得 a[j][j]
for (int k = 1; k <= col; k++)
{
if (j == k)
{
continue;
}
if (k != col)
{
// 如果 j 不等于 k 且不等于常数项的下标,则每一项等于系数与对应迭代初值的乘积
item = a[j][k] * b[k];
}
else
{
// j=col 即常数项下标时,直接加上常数项,不对常数项处理
item = a[j][col];
}
// 累加 item,求得 a[1][1], a[2][2]......
a[j][j] += item;
}
// 输出 a[1][1], a[2][2]......
cout << "\t\t" << a[j][j] << "\t\t";
// 将a[1][1], a[2][2]......暂存到数组 c
c[count] = a[count][count];
// 赋 a[1][1], a[2][2]......值为 0,避免拥有初值影响下一次迭代结果
a[count][count] = 0;
if (count % (col - 1) == 0)
cout << endl;
count++;
}
// 将 c 数组中的值赋值给 b 数组,进入下次循环
for (int i = 1; i < col; i++)
b[i] = c[i];
}
return 0;
}