Метод Зейделя решения СЛАУ (реализация на Java)

Java   30 Январь 2012  Автор статьи:  

На вход алгоритму подается матрица, задающая систему линейных уравнений, которую требуется разрешить, а также задается точность, которую необходимо обеспечить. На выходе алгоритм выдает найденное решение, все вычисления проводятся с типом данных double для повышения точности. Для того, чтобы целая часть вещественного числа отделялась от дробной точкой, а не запятой, необходимо установить русский Locale.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import java.io.PrintWriter;
import java.util.Locale;
import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        // Для считывания воспользуемся классом Scanner
        Scanner scanner = new Scanner(System.in);
        // Для того, чтобы целая часть вещественного числа
        // отделялась от дробной точкой, а не запятой,
        // необходимо установить русский Locale
        scanner.useLocale(new Locale("Russian"));

        // Для вывода - классом PrintWriter
        PrintWriter printWriter = new PrintWriter(System.out);

        // Считываем размер вводимой матрицы
        int size;
        size = scanner.nextInt();

        // Будем хранить матрицу в векторе, состоящем из
        // векторов вещественных чисел
        double[][] matrix = new double[size][size + 1];

        // Матрица будет иметь размер (size) x (size + 1),
        // c учетом столбца свободных членов        
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size + 1; j++) {
                matrix[i][j] = scanner.nextDouble();
            }
        }

        // Считываем необходимую точность решения
        double eps;
        eps = scanner.nextDouble();

        // Введем вектор значений неизвестных на предыдущей итерации,
        // размер которого равен числу строк в матрице, т.е. size,
        // причем согласно методу изначально заполняем его нулями
        double[] previousVariableValues = new double[size];
        for (int i = 0; i < size; i++) {
            previousVariableValues[i] = 0.0;
        }

        // Будем выполнять итерационный процесс до тех пор,
        // пока не будет достигнута необходимая точность
        while (true) {
            // Введем вектор значений неизвестных на текущем шаге
            double[] currentVariableValues = new double[size];

            // Посчитаем значения неизвестных на текущей итерации
            // в соответствии с теоретическими формулами
            for (int i = 0; i < size; i++) {
                // Инициализируем i-ую неизвестную значением
                // свободного члена i-ой строки матрицы
                currentVariableValues[i] = matrix[i][size];

                // Вычитаем сумму по всем отличным от i-ой неизвестным
                for (int j = 0; j < size; j++) {
                    // При j < i можем использовать уже посчитанные
                    // на этой итерации значения неизвестных
                    if (j < i) {
                        currentVariableValues[i] -= matrix[i][j] * currentVariableValues[j];
                    }

                    // При j > i используем значения с прошлой итерации
                    if (j > i) {
                        currentVariableValues[i] -= matrix[i][j] * previousVariableValues[j];
                    }
                }

                // Делим на коэффициент при i-ой неизвестной
                currentVariableValues[i] /= matrix[i][i];
            }

            // Посчитаем текущую погрешность относительно предыдущей итерации
            double error = 0.0;

            for (int i = 0; i < size; i++) {
                error += Math.abs(currentVariableValues[i] - previousVariableValues[i]);
            }

            // Если необходимая точность достигнута, то завершаем процесс
            if (error < eps) {
                break;
            }

            // Переходим к следующей итерации, так
            // что текущие значения неизвестных
            // становятся значениями на предыдущей итерации
            previousVariableValues = currentVariableValues;
        }

        // Выводим найденные значения неизвестных
        for (int i = 0; i < size; i++) {
            printWriter.print(previousVariableValues[i] + " ");
        }

        // После выполнения программы необходимо закрыть
        // потоки ввода и вывода
        scanner.close();
        printWriter.close();
    }
}
  • Traglod1t1

    выложите, пожалуйста, конкретный пример(что, куда и как вводится) с решением.

    • ZennonBSide

      Ввод/вывод в программе осуществляется с экрана и на экран консоли. Пусть, например, требуется решить СЛАУ следующего вида:

      x + y + z = 5,
      x + 2*y + 2*z = -3,
      x + 2*y + 3*z = 6.

      Тогда программе нужно передать число неизвестных в системе, а затем матрицу коэффициентов, включая столбец свободных членов. Последним числом нужно передать допустимую погрешность, на которое приближенное решение может отличаться от точного. Итого, входные данные для данной матрицы будут выглядеть так:

      3
      1 1 1 5
      1 2 2 -3
      1 2 3 6
      0.0001

      В качестве результата программа выведет приближенные значения неизвестных
      12.999906137602311 -16.9999061329457 8.999968709429696
      которые лишь незначительно отличаются от точного решения данной системы
      x = 13,
      y = -17,
      z = 9.

  • Victor Nikolaenko

    Случайно нет реализации на JavaScript?

    • http://cybern.ru/ lordrp

      Реализация на javascript отличалась бы только вводом, ну и мелкими моментами.

Научиться программировать

  • на Delphi

  • на Java

  • на C++