Решение систем линейных уравнений методом Крамера

Решение систем линейных уравнений методом Крамера

Для решения системы n линейных уравнений с n неизвестными xi, представленной в виде

{\displaystyle {\begin{cases}a_{11}x_{1}+a_{12}x_{2}+\ldots +a_{1n}x_{n}=b_{1}\\a_{21}x_{1}+a_{22}x_{2}+\ldots +a_{2n}x_{n}=b_{2}\\\cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \cdots \\a_{n1}x_{1}+a_{n2}x_{2}+\ldots +a_{nn}x_{n}=b_{n}\\\end{cases}}}

с определителем матрицы системы Δ, отличным от нуля, решение для каждой неизвестной xi записывается в виде

{\displaystyle x_{i}={\frac {\Delta_{i}}{\Delta }}}

где

{\displaystyle {\Delta_{i}}={\begin{vmatrix}a_{11}&\ldots &a_{1,i-1}&b_{1}&a_{1,i+1}&\ldots &a_{1n}\\a_{21}&\ldots &a_{2,i-1}&b_{2}&a_{2,i+1}&\ldots &a_{2n}\\\ldots &\ldots &\ldots &\ldots &\ldots &\ldots &\ldots \\a_{n-1,1}&\ldots &a_{n-1,i-1}&b_{n-1}&a_{n-1,i+1}&\ldots &a_{n-1,n}\\a_{n1}&\ldots &a_{n,i-1}&b_{n}&a_{n,i+1}&\ldots &a_{nn}\\\end{vmatrix}}}

То есть для нахождения каждой неизвестной xi в линейной системе необходимо вычислить отношение определителей двух матриц. В знаменателе формируется определитель исходной матрицы коэффициентов, а в числителе формируется определитель исходной матрицы коэффициентов, в которой i-ый столбец заменен значениями свободных членов из правой части системы линейных уравнений.

В качестве примера рассмотрим решение системы линейных уравнений

{\displaystyle {\begin{cases}-10x_{0}+7x_{1}+7x_{2}-2x_{3}=159\\3x_{0}+2x_{1}+7x_{2}-x_{3}=2\\ 3x_{0}+6x_{1}+2x_{2}-2x_{3}=31\\8x_{0}+7x_{1}+3x_{2}-7x_{3}=43\\\end{cases}}}

{\displaystyle x_{0}={\frac {\begin{vmatrix}159 &7 &7 &-2\\2 &2 &7 &-1\\31 &6 &2 &-2\\43 &7 &3 &-7\\\end{vmatrix}}{\begin{vmatrix}-10 &7 &7 &-2\\3 &2 &7 &-1\\3 &6 &2 &-2\\8 &7 &3 &-7\\\end{vmatrix}}}=-9}

{\displaystyle x_{1}={\frac {\begin{vmatrix}-10 &159 &7 &-2\\3 &2 &7 &-1\\3 &31 &2 &-2\\8 &43 &3 &-7\\\end{vmatrix}}{\begin{vmatrix}-10 &7 &7 &-2\\3 &2 &7 &-1\\3 &6 &2 &-2\\8 &7 &3 &-7\\\end{vmatrix}}}=6}

{\displaystyle x_{2}={\frac {\begin{vmatrix}-10 &7 &159 &-2\\3 &2 &2 &-1\\3 &6 &31 &-2\\8 &7 &43 &-7\\\end{vmatrix}}{\begin{vmatrix}-10 &7 &7 &-2\\3 &2 &7 &-1\\3 &6 &2 &-2\\8 &7 &3 &-7\\\end{vmatrix}}}=1}

{\displaystyle x_{3}={\frac {\begin{vmatrix}-10 &7 &7 &159\\3 &2 &7 &2\\3 &6 &2 &31\\8 &7 &3 &43\\\end{vmatrix}}{\begin{vmatrix}-10 &7 &7 &-2\\3 &2 &7 &-1\\3 &6 &2 &-2\\8 &7 &3 &-7\\\end{vmatrix}}}=-10}

Реализация на Си

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
105
106
107
108
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
// Функция освобождения памяти, выделенной под матрицу
void Free(double** mas, int rows)
{
  if (mas == 0) return;    // если память не была выделена, выходим
  for (int i = 0; i < rows; i++)
    free(mas[i]);
  free(mas);
}

// Получение матрицы без i-й строки и j-го столбца
// (функция нужна для вычисления определителя и миноров)
double** GetMatr(double** mas, int rows, int cols, int row, int col) {
  int di, dj;
  double** p = (double**)malloc((rows - 1) * sizeof(double*));
  di = 0;
  for (int i = 0; i < rows - 1; i++) { // проверка индекса строки
    if (i == row)  // строка совпала с вычеркиваемой
      di = 1;    // - дальше индексы на 1 больше
    dj = 0;
    p[i] = (double*)malloc((cols - 1) * sizeof(double));
    for (int j = 0; j < cols - 1; j++) { // проверка индекса столбца
      if (j == col)  // столбец совпал с вычеркиваемым
        dj = 1;    // - дальше индексы на 1 больше
      p[i][j] = mas[i + di][j + dj];
    }
  }
  return p;
}

// Рекурсивное вычисление определителя
double Determinant(double** mas, int m) {
  int k;
  double** p = 0;
  double d = 0;
  k = 1; //(-1) в степени i
  if (m < 1) { printf("Определитель вычислить невозможно!"); return 0; }
  if (m == 1) { d = mas[0][0]; return(d); }
  if (m == 2) { d = mas[0][0] * mas[1][1] - (mas[1][0] * mas[0][1]); return(d); }
  if (m > 2) {
    for (int i = 0; i < m; i++) {
      p = GetMatr(mas, m, m, i, 0);
      d = d + k * mas[i][0] * Determinant(p, m - 1);
      k = -k;
    }
  }
  Free(p, m - 1);
  return d;
}

// Основная функция
int main() 
{
  int n, d;
  double** mas;
  double* b;
  system("chcp 1251");
  system("cls");
  printf("Введите размерность квадратной матрицы: ");
  scanf("%d", &n);
  mas = (double**)malloc(n * sizeof(double*));
  b = (double*)malloc(n * sizeof(double));
  printf("Введите коэффициенты матрицы: \n");
  for (int i = 0; i < n; i++) 
  {
    mas[i] = (double*)malloc(n * sizeof(double));
    for (int j = 0; j < n; j++) {
      printf("a[%d][%d]= ", i, j);
      scanf("%lf", &mas[i][j]);
    }
  }
  printf("Введите свободные члены: \n");
  for (int i = 0; i < n; i++)
  {
    printf("b[%d]=", i);
    scanf("%lf", &b[i]);
  }
  d = Determinant(mas, n);
  // матрица со столбцом из свободных членов
  double** h = (double**)malloc(n * sizeof(double*));
  for (int i = 0; i < n; i++)
    h[i] = (double*)malloc(n * sizeof(double));
  // массив определителей
  double* det = (double*)malloc(n * sizeof(double));
  for (int k = 0; k < n; k++) // для каждой неизвестной
  {
    for (int i = 0; i < n; i++)
    {
      for (int j = 0; j < n; j++)   // заполняем коэффициенты исходной матрицы
      {
        if (j != k)
          h[i][j] = mas[i][j];
        else
          h[i][k] = b[i];     // заменяем столбец свободных членов
      }
    }
    det[k] = Determinant(h, n); // получаем определитель матрицы числителя
  }
  for (int i = 0; i < n; i++)   // вычисляем неизвестные как отношение определителей
    det[i] = det[i] / d;
  printf("Результат: \n");
  for (int i = 0; i < n; i++)
    printf("x[%d] = %lf\n", i,det[i]);
  getchar(); getchar();
  return 0;
}

Результат выполнения

Метод Крамера - результат выполнения

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх