雅克比迭代-高斯赛德尔-SOR迭代

一、代码实现(Java)
package shuzhijisuan;

//使用迭代法解线性方程组---雅克比方法、高斯-赛德尔方法、逐次超松弛法
public class Shuzhijisuan {

/**
* 雅克比方法求解
*
* @param A
* @param b
* @param x
* @param escape
* @param max
* @return
*/
public double[] Jacobi(double[][] A, double[] b, double[] x, double escape, int max) {
int line1 = A.length;// 位置参数的个数
int line2 = A[0].length;// 列数

double s = 0;// 精度
int count = 0;// 迭代次数
double temp = 0;

double[] tempX = new double[line1];// 存储改变后的x数组值

do {
s = 0.0;
System.out.println("第" + count + "次迭代");
for (int i = 0; i < line1; i++) {
System.out.print(x[i] + " ");
}
System.out.println();

if (count > max) {
System.out.println("雅克比不收敛");//比较次数后做出判断。
return null;
} else {
for (int i = 0; i < line1; i++) {// 解分量
for (int j = 0; j < line2; j++) {
if (i != j) {
temp = (double) (temp + (double) (A[i][j] * x[j]));
}
}

tempX[i] = (double) ((b[i] - temp) / A[i][i]);// 迭代后的结果
s += Math.abs((double) (tempX[i] - x[i]));// 求出误差
temp = 0;
}

// 调整x数组的值
for (int i = 0; i < line1; i++) {
x[i] = tempX[i];
}
count++;
}

} while ((s - escape) > 0);

return x;
}

/**
* 高斯——赛德尔方法
* @param A
* @param b
* @param x
* @param escape
* @param max
* @return
*/
public double[] Gauss_Sedea(double[][] A, double[] b, double[] x, double escape, int max) {
int line1 = A.length;// 位置参数的个数
int line2 = A[0].length;// 列数

double s = 0;// 精度
int count = 0;// 迭代次数
double temp1 = 0, temp2 = 0;

do {
s = 0.0;
System.out.println("第" + count + "次迭代");
for (int i = 0; i < line1; i++) {
System.out.print(x[i] + " ");
}
System.out.println();

for (int i = 0; i < line1; i++) {
for (int j = 0; j < line2; j++) {
if (i != j) {
temp1 = (double) (temp1 + (double) (A[i][j] * x[j]));
}
}

temp2 = x[i];
x[i] = (double) ((b[i] - temp1) / A[i][i]);
s += Math.abs((double) (x[i] - temp2));
temp1 = 0;
}

count++;

} while ((s - escape) > 0);

return x;
}

/**
* 逐次超松弛法
* @param A
* @param b
* @param x
* @param escape
* @param max
* @param factor
* @return
*/
public double[] successive_over_relaxation_method(double[][] A, double[] b, double[] x, double escape, int max, double factor) {
int line1 = A.length;// 位置参数的个数
int line2 = A[0].length;// 列数

double s = 0;// 精度
int count = 0;// 迭代次数
double temp1 = 0, temp2 = 0;

do {
s = 0.0;
System.out.println("第" + count + "次迭代");
for

(int i = 0; i < line1; i++) {
System.out.print(x[i] + " ");
}
System.out.println();

for (int i = 0; i < line1; i++) {
for (int j = 0; j < line2; j++) {
if (i != j) {
temp1 = (double) (temp1 + (double) (A[i][j] * x[j]));
}
}

temp2 = x[i];
x[i] = (double) ((b[i] - temp1) / A[i][i]);
x[i] = (double) ((1 - factor) * temp2 + (double) (factor * x[i]));

s += Math.abs((double) (x[i] - temp2));
temp1 = 0;

}
count++;
} while ((s - escape) > 0);

return x;
}

/**
* 输出结果
*
* @param x
*/
public void outPut(double[] x) {
System.out.println("\n该结果是");
for (int i = 0; i < x.length; i++) {
System.out.println("x[" + (i + 1) + "]=" + x[i]);
}
}

public static void main(String[] args) {

double[][] matrix = { { 4, -1, -1, 0 }, { -1, 4, 0, -1 }, { -1, 0, 4, -1 }, { 0, -1, -1, 4 } };

double[] b = { 0, 0, 1, 1 };
double[] x1 = { 0, 0, 0, 0 }, x2 = { 0, 0, 0, 0 }, x3 = { 0, 0, 0, 0 };

Shuzhijisuan shiyan = new Shuzhijisuan();

System.out.println("++++++++++++++++++++雅克比+++++++++++++++");
shiyan.Jacobi(matrix, b, x1, 0.003, 10);
shiyan.outPut(x1);
System.out.println("++++++++++++++++++++高斯-赛德尔+++++++++++++++");
shiyan.Jacobi(matrix, b, x2, 0.003, 10);
shiyan.outPut(x2);
System.out.println("+++++++++++++++++++逐次超松弛++++++++++++++");
shiyan.successive_over_relaxation_method(matrix, b, x3, 0.003, 100, 1.072);
shiyan.outPut(x3);
}

}

二、输出结果
++++++++++++++++++++雅克比+++++++++++++++
第0次迭代
0.0 0.0 0.0 0.0
第1次迭代
0.0 0.0 0.25 0.25
第2次迭代
0.0625 0.0625 0.3125 0.3125
第3次迭代
0.09375 0.09375 0.34375 0.34375
第4次迭代
0.109375 0.109375 0.359375 0.359375
第5次迭代
0.1171875 0.1171875 0.3671875 0.3671875
第6次迭代
0.12109375 0.12109375 0.37109375 0.37109375
第7次迭代
0.123046875 0.123046875 0.373046875 0.373046875
第8次迭代
0.1240234375 0.1240234375 0.3740234375 0.3740234375

该结果是
x[1]=0.12451171875
x[2]=0.12451171875
x[3]=0.37451171875
x[4]=0.37451171875


++++++++++++++++++++高斯-赛德尔+++++++++++++++
第0次迭代
0.0 0.0 0.0 0.0
第1次迭代
0.0 0.0 0.25 0.25
第2次迭代
0.0625 0.0625 0.3125 0.3125
第3次迭代
0.09375 0.09375 0.34375 0.34375
第4次迭代
0.109375 0.109375 0.359375 0.359375
第5次迭代
0.1171875 0.1171875 0.3671875 0.3671875
第6次迭代
0.12109375 0.12109375 0.37109375 0.37109375
第7次迭代
0.123046875 0.123046875 0.373046875 0.373046875
第8次迭代
0.1240234375 0.1240234375 0.3740234375 0.3740234375

该结果是
x[1]=0.12451171875
x[2]=0.12451171875
x[3]=0.37451171875
x[4]=0.37451171875


+++++++++++++++++++逐次超松弛++++++++++++++
第0次迭代
0.0 0.0 0.0 0.0
第1次迭代
0.0 0.0 0.268 0.339824
第2次迭代
0.07182400000000001 0.11032166400000001 0.35902566399999

997 0.369317755904
第3次迭代
0.120613755904 0.123358485356544 0.37345179735654394 0.3745542773420196
第4次迭代
0.12446096534201956 0.12485427409365135 0.37484755562965133 0.3749521823972197

该结果是
x[1]=0.1249589008612197
x[2]=0.12498666257851887
x[3]=0.3749871463079269
x[4]=0.3749964236489677

三、分析:
结果:由于java本身的特性,会导致本身浮点数不精确。
原理: 雅克比迭代法的优点明显,计算公式简单,每迭代一次只需计算一次矩阵和向量的乘法,且计算过程中 原始矩阵A始终不变,比较容易并行计算。然而这种迭代方式收敛速度较慢,而且占据的存储空间较大 ,所以工程中一般不直接用雅克比迭代法,而用其改进方法。
高斯塞德尔迭代法比雅可比迭代法收敛较快。
超松弛迭代法中松弛因子的选择很重要,松弛因子选择的好,会使迭代法的收敛大大加速。

相关文档
最新文档