【问题标题】:Gauss Seidel Method高斯赛德尔法
【发布时间】:2015-04-02 20:56:18
【问题描述】:

我写了一个 Gauss-Seidel 方法来计算矩阵 A 的未知 x 值。另一种在线方法似乎首先检查行列式是否包含非零,但其他算法,包括我的教授的笔记,没有验证检查。

所以我现在只是按照教授在课堂上给出的算法,我认为第一个xNew是正确的,因为我在我的计算器上验证了它,但是我的其他x值没有更新,有人知道为什么吗?

public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;

do{
  double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
  double[] xOld = new double[b.length]; 

  for(int i = 0; i < A.length; i++){ 
    double sum = 0.0;
    double sum1 = 0.0;
    for(int j = 0; j < A.length; j++){

      if( j != i)
        sum += (A[i][j]*xOld[j]);

     sum1 += (A[i][j]*xNew[j]);
    }

    xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
    System.out.println("X_" + (i+1) + ": " + xNew[i]);
    System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
    System.out.println("");
    count++;

    if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
      xNew[i] = xOld[i];
      }

    else{
      stop = true;}   
  }
}while( !stop && count <= MAX_ITERATIONS);
}

我的矩阵:
double[][] a = {{12,-2,1,0,0,0,0,0,0,0,0}, {-2,12,2,1,0,0,0,0,0,0,0}, {1,-2,12,-2,1,0,0,0,0,0,0}, {0,1,-2,12,-2,1,0,0,0,0,0}, {0,0,1,-2,12,2,1,0,0,0,0}, {0,0,0,1,-2,12,-2,1,0,0,0}, {0,0,0,0,1,-2,12,-2,1,0,0},{0,0,0,0,0,1,-2,12,-2,1,0}, {0,0,0,0,0,0,1,-2,12,-2,0},{0,0,0,0,0,0,0,1,-2,12,0}};

我的 b 值:

double[] b = {13.97, 5.93, -6.02, 8.32, -23.75, 28.45, -8.9, -10.5, 10.34, -38.74};

【问题讨论】:

  • 还有哪些其他 x 值?你可以说得更详细点吗?您还可以发布一个带有小矩阵的示例,以便我们测试任何建议的解决方案吗?
  • @I.K.,我有一个具有给定值的 10×10 矩阵,因此根据算法,“旧值:x_2,x_3,...”最初应为 0,即我怎么知道第一次迭代的 x_1 应该是 ~1.16416667。但是这个值应该随着每次迭代而改变,直到它的误差小于 epsilon,这不会发生。这就是我的意思,但我会同时发布double[][]adouble[]b。任何建议都会有所帮助!
  • 看起来你在每次迭代后都在破坏你的矩阵。
  • @I.K.,这到底是什么意思?就像我压倒它一样?
  • 是的。我在下面发布了我的建议。

标签: java matrix linear-algebra gaussian


【解决方案1】:

每次循环时,都会一次又一次地创建以下数组:

  double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
  double[] xOld = new double[b.length]; 

当然,您正在丢失在前一个循环中计算的值。我认为你只需要创建一次,所以在你的循环之外如下:

public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;

double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length]; 

do{

  for(int i = 0; i < A.length; i++){ 
    double sum = 0.0;
    double sum1 = 0.0;
    for(int j = 0; j < A.length; j++){

      if( j != i)
        sum += (A[i][j]*xOld[j]);

     sum1 += (A[i][j]*xNew[j]);
    }

    xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
    System.out.println("X_" + (i+1) + ": " + xNew[i]);
    System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
    System.out.println("");
    count++;

    if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
      xNew[i] = xOld[i];
      }

    else{
      stop = true;}   
  }
}while( !stop && count <= MAX_ITERATIONS);
}

【讨论】:

  • 当然可以!!但即使我从 do-while 循环中删除它,我的 x 值也没有按应有的方式更新,所以我意识到这可能只是我的许多错误之一。
  • 是的。您现在有一个很好的平台可以继续纠正其他错误。您用来索引b 数组的for 循环中的i 变量看起来非常 可疑。您可能最终会遇到这样一种情况,即您尝试在数组“之外”建立索引,这会导致程序崩溃。
猜你喜欢
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 2011-02-03
  • 1970-01-01
  • 2013-03-19
相关资源
最近更新 更多