jacobi 迭代方法在 C++ 中有错误的答案

jacobi iterative method has wrong answer in c++

我正在编写 Jacobi 迭代法来求解任何线性方程组。该程序适用于某些示例,但不适用于其他示例。例如

A=     and B=
7  3       5
2  3       4

这将有效,答案是正确的,但对于

A=     and B=
1  2       3
3  4       7

答案是错误的,而且数字很大。 我真的不知道我应该怎么做才能做出正确的计算。 我使用了一些其他代码,但我仍然遇到代码问题。

#include <iostream>
using namespace std;

int main(){
    double A[10][10], alpha[10][10], B[10], betha[10], x[10][100], sum[10];
    int i, j, n, k, kmax;
    cout << "insert number of equations \n";
    cin >> n;
    cout << "insert LHS of equations (a11,a12,...,ann)\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cin >> A[i][j];
        }
    }
    cout << "A=\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cout << A[i][j] << "\t\t";
        }
        cout << "\n\n";
    }
    cout << "alpha=\n";
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            if (i == j){
                alpha[i][j] = 0;
            }
            else{
                alpha[i][j] = -A[i][j] / A[i][i];
            }
        }
    }
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            cout << alpha[i][j] << "\t\t";
        }
        cout << "\n\n";
    }
    cout << "insert RHS of equations";
    for (i = 1; i <= n; i++){
        cin >> B[i];
    }
    cout << "\nbetha=\n";
    for (i = 1; i <= n; i++){
        betha[i] = B[i] / A[i][i];
        cout << betha[i] << endl;
    }
    cout << "Enter the number of repetitions." << endl;
    cin >> kmax;
    k = 0;
    for (i = 1; i <= n; i++){
        sum[i] = 0;
        x[i][k] = betha[i];    //initial values 
    }
    for (k = 0; k <= kmax; k++){
        for (i = 1; i <= n; i++){
            for (j = 1; j <= n; j++){
                sum[i] += alpha[i][j] * x[j][k];
            }
            x[i][k] = betha[i] + sum[i];
            sum[i] = 0; 
        }
    }
    cout << "answers:\n\n";
    for (i = 1; i <= n; i++){
        cout << x[i][kmax] << endl;
    }
    return 0;
}

您应该再次检查收敛条件。在那里你会发现通常该方法只收敛对角占优矩阵。第一个示例满足该条件,而第二个示例明显违反了该条件。

如果不能保证收敛,可能会出现发散,如您所见。


更具体地说,第二个例子中的雅可比迭代计算

xnew[0] = (3 - 2*x[1])/1;
xnew[1] = (7 - 3*x[0])/4;

经过两次迭代,步骤的组合给出

xtwo[0] = (3 - 2*xnew[1])/1 = -0.5 + 1.5*x[0];
xtwo[1] = (7 - 3*xnew[0])/4 = -0.5 + 1.5*x[1];

这显然是在用因子 1.5 扩大初始误差。

您的矩阵按行顺序排列为:[{1, 2} {3, 4}]

行列式等于-2;显然不是单数。

它有逆:[{4, -2}, {-3, 1}]/(-2)

正确答案是:{1, 1}

您可以通过代回原始方程式并检查以确保您有一个恒等式来验证这一点:[{1, 2} {3, 4}]{1, 1} = {3, 7}

迭代方法可能对初始条件敏感。

关于对角占优的观点是正确的。也许更明智地选择初始条件,更接近正确答案,会让你收敛。

更新:

Jacobi迭代将矩阵分解为对角线元素D和非对角线元素R:

如果满足以下条件,Jacobi 将收敛:

由于样本矩阵的第一行不是这种情况,您可能遇到了问题。

如果您使用正确答案作为初始猜测,您仍然只需一步就可以到达那里。这表示即使是 Jacobi 也会做出明智的选择。

如果我从 {1, 1} 开始,我会在一次迭代中收敛到正确答案。