当然,很难详细介绍所有方法,但是对我来说,这个话题似乎很有趣并且非常重要,因为每个人都面临着经常找到解决方案的任务。 在第一篇文章
为什么是高斯? 描述了高斯方法(包括修改)和一些迭代方法。 但是,鉴于对
Sinn3r的批评,我决定也描述其他方法。
重新开始
因此,让我们再次需要求解线性代数方程组
。 最引人注目的数值方法之一是使用
-分解矩阵。
这种直观的方法如下。 假设我们有一个线性代数方程组(以矢量形式编写):
在哪里
-可怕且令人困惑的
非退化矩阵。 我们将其表示为另外两个矩阵的乘积:
是下三角矩阵,并且
是上三角矩阵。 那么显然,系统采用以下形式:
如果指定
,则可以从其他两个系统的解决方案中找到原始系统的解决方案:

这种方法的优点是两个辅助系统的解非常简单(由于矩阵
和

-三角形)。 但是找到这些矩阵容易吗? 因此,将系统求解的任务简化为构建的任务
-矩阵分解。
算法应用说明
-分解在
这里有足够详细的描述。 同时,我们将介绍另一种方法。
平方根法
我们在矩阵上附加条件
。 我们要求它是对称的,即
或
。 这样的矩阵可以表示为
在哪里
-上三角矩阵,
是对角
实矩阵,其对角元素的绝对值等于1。 同样,原始系统简化为另外两个:
由于矩阵的性质,它们也可以基本解决
和
。
算法公式的推导相当麻烦,并且超出了公开范围。 如果需要,可以在
这里找到它们。
实现sweep方法的示例Java代码:
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; import java.util.Locale; import java.util.Scanner; public class SquareRootMethod { public static void main(String[] args) throws FileNotFoundException { Scanner scanner = new Scanner(new FileReader("input.txt")); scanner.useLocale(Locale.US); int n = scanner.nextInt(); double[][] a = new double[n + 1][n + 1]; double[] b = new double[n + 1]; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { a[i][j] = scanner.nextDouble(); } b[i] = scanner.nextDouble(); } double[] x = new double[n + 1]; double[] d = new double[n + 1]; double[][] s = new double[n + 1][n + 1];
扫描方式
使用此方法,只能求解每行中不超过三个未知数的特定系统。 也就是说,有了系统
矩阵
是三对角的:
请注意,附近的解决方案之间存在联系:
-一些未知的数字。 如果找到它们和一个变量,则可以找到所有其他变量。
公式的推导
在
这里 。 好吧,最后
请注意,在搜索公式中
有一个除数
可能是零,需要跟踪。 但实际上,以下
语句成立,其证明在
这里 :如果满足条件,则扫描算法正确且稳定:
考虑解决系统问题的Java程序代码。
\ left \ {\ begin {aligned}&x_1 = 0,\\&x_ {i-1} + \ xi x_ {i + 1} = \ dfrac {i} {n},\(i = \ overline {2, n-1}),\\&x_n = 1,\\ \结束{aligned} \ right
在
。
package SystemOfLinearAlgebraicEquations; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; import java.util.Locale; import java.util.Scanner; public class TridiagonalMatrixAlgorithm { public static void main(String[] args) throws FileNotFoundException { final int n = 21; double[] A = new double[n + 1]; double[] B = new double[n + 1]; double[] C = new double[n + 1]; double[] F = new double[n + 1]; double xi = 2; C[1] = 1; F[1] = 0; for(int i = 2; i <= n-1; i++) { A[i] = 1; C[i] = xi; B[i] = 1; F[i] = - (double) i / n; } A[n] = 0; C[n] = 1; F[n] = 1; double[] alpha = new double[n + 1]; double[] beta = new double[n + 1];