|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
| SPIS TREŚCI REMANENT |
|
| Podrozdziały |
W poprzednim rozdziale rozwiązaliśmy układ dwóch równań liniowych:

Wyprowadziliśmy wzór na zmienną x:

Wyprowadźmy analogiczny wzór na zmienną y:

Ostatecznie:


Przyjrzyj się tym wzorom. W obu wzorach mianowniki ułamków są tym samym wyrażeniem. Różne są liczniki. Jeśli potraktujemy liczniki i mianowniki tych ułamków jako wyznaczniki macierzy drugiego stopnia, to:

Zapiszmy nasz układ równań w postaci macierzowej:

Macierz A jest macierzą współczynników stojących przy niewiadomych:

Macierz Ax powstaje z macierzy A, gdy kolumnę współczynników zmiennej x zastąpimy macierzą wyrazów wolnych B:

Macierz Ay powstaje z macierzy A, gdy kolumnę współczynników zmiennej y zastąpimy macierzą wyrazów wolnych B:

Układ posiada rozwiązanie, jeśli wyznacznik macierzy A jest różny od 0. Wykorzystując wyznaczniki, możemy teraz zapisać:

Wzory, które otrzymaliśmy w poprzednim podrozdziale, nie są przypadkowe. Matematyk szwajcarski Gabriel Cramer pokazał, iż za pomocą wyznaczników można rozwiązywać układy równań liniowych. Są to tak zwane wzory Cramera (ang. Cramer's rule).
Mamy układ n równań z n niewiadomymi:

Zapiszmy ten układ równań w postaci macierzowej:

Macierz kwadratowa A stopnia n jest macierzą współczynników a, które stoją przy niewiadomych x.
Wektor X jest macierzą niewiadomych x.
Wektor B jest macierzą współczynników wolnych b.
Oznaczmy przez Xi macierz, która powstaje z macierzy A przez zastąpienie wyrazów w kolumnie i-tej wyrazami wektora B:

Wartości zmiennych układu równań obliczamy ze wzorów Cramera:

Układ posiada rozwiązanie, jeśli wyznacznik macierzy współczynników A jest różny od zera. Jeśli wyznacznik macierzy A jest równy zero, to układ równań jest albo sprzeczny (nie posiada rozwiązań) , albo nieoznaczony (posiada więcej niż jedno rozwiązanie).
Dla n niewiadomych x metoda Cramera wymaga policzenia n + 1 wyznaczników stopnia n. Powoduje to, iż ma ona klasę złożoności obliczeniowej równą O(n4), jeśli wyznaczniki są liczone za pomocą rozkładu LU. Istnieją lepsze metody rozwiązywania układów równań liniowych.
Przykład:
Rozwiązać układ równań:

Układ zapisujemy macierzowo:

Obliczamy wyznacznik macierzy współczynników A. Wykorzystujemy schemat Saurrusa:

Obliczamy wyznacznik macierzy X1:

Obliczamy wyznacznik macierzy X2:

Obliczamy wyznacznik macierzy X3:

Obliczamy niewiadome:

Sprawdzamy, czy wyliczone wartości niewiadomych spełniają równania:

Poniższy program rozwiązuje za pomocą wzorów Cramera układ równań liniowych. Program zawiera funkcję obliczającą wyznacznik macierzy, która wykorzystuje rozkład LU z piwotowaniem. Dane wejściowe do programu wyglądają następująco:
Pierwsza liczba n określa ilość równań w układzie. Następne n wierszy po n liczb definiują współczynniki a przy niewiadomych. Ostatni wiersz zawiera n liczb definiujących wyrazy wolne b.Układ równań:

|
Dane wejściowe:
5 -1 2 -3 3 5 8 0 7 4 -1 -3 4 -3 2 -2 8 -3 -2 1 2 -2 -1 -6 9 0 56 62 -10 14 28 |
C++// Wzory Cramera
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne 0066
//---------------------------
#include <iostream>
#include <windows.h>
#include <iomanip>
#include <cmath>
using namespace std;
const double EPS = 0.000000001;
// Funkcja oblicza wartość
// wyznacznika macierzy
// metodą rozkładu LU
// z piwotowaniem
// n - stopień macierzy
// A - wskaźnik macierzy
//----------------------
double det(int n, double ** A)
{
int i, j, k, * W, md, maxw;
double sc, akk, maxe;
// Mnożnik korekcyjny
// dla wyznacznika
md = 1;
// Tworzymy wektor wierszowy
W = new int [n];
// Inicjujemy wektor wierszowy
// numerami wierszy
for(i = 0; i < n; i++)
W[i] = i;
// Rozkład LU
for(k = 0; k < n; k++)
{
// numer wiersza
// z elementem max
maxw = k;
maxe = fabs(A[W[k]][k]);
// Szukamy elementu max
for(i = k + 1; i < n; i++)
if(fabs(A[W[i]][k]) > maxe)
{
maxw = i;
maxe = fabs(A[W[i]][k]);
}
// Jeśli max jest zero,
// to macierz jest
// zdegenerowana
if(maxe <= EPS)
return 0;
// Jeśli max nie leży
// na przekątnej,
// zamieniamy wiersze
if(maxw != k)
{
// Modyfikujemy mnożnik
md = -md;
swap(W[k], W[maxw]);
}
// Dzielnik
akk = A[W[k]][k];
// Normalizujemy kolumnę
for(i = k + 1; i < n; i++)
A[W[i]][k] /= akk;
// Modyfikujemy podmacierz
for(i = k + 1; i < n; i++)
for(j = k + 1; j < n; j++)
A[W[i]][j] -= A[W[i]][k]
* A[W[k]][j];
}
// Obliczamy wyznacznik;
sc = md;
for(k = 0; k < n; k++)
sc *= A[W[k]][k];
delete [] W;
return sc;
}
// Program główny
//---------------
int main()
{
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
cout << setprecision(5)
<< fixed;
cout
<< "Rozwiązywanie układu "
"równań liniowych "
"wzorami Cramera\n"
"---------------------"
"-----------------"
"---------------\n\n"
"Wpisz dane "
"wejściowe:\n\n";
// Indeksy
int i,j,k;
// Liczba równań w układzie
int n;
cin >> n;
// Tworzymy dynamicznie
// potrzebne macierze
// Macierz współczynników
// przy niewiadomych x
double ** A;
// Macierz pomocnicza
double ** Xi;
A = new double * [n];
Xi = new double * [n];
for(i = 0; i < n; i++)
{
A[i] = new double[n];
Xi[i] = new double[n];
}
// Odczytujemy współczynniki
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
cin >> A[i][j];
Xi[i][j] = A[i][j];
}
// Macierz wyrazów wolnych
double * B;
B = new double[n];
// Odczytujemy wyrazy wolne
for(i = 0; i < n; i++)
cin >> B[i];
cout << endl;
// Rozpoczynamy od obliczenia
// wyznacznika macierzy A
double detA = det(n,Xi);
if(fabs(detA)< EPS)
cout <<
"Układ równań nie "
"ma rozwiązania\n";
else
{
// Tworzymy macierz rozwiąń
double * X = new double[n];
// Rozpoczynamy wyliczanie
// niewiadomych
for(k = 0; k < n; k++)
{
// Ustawiamy macierz
// pomocniczą Xi
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
if(j == k)
Xi[i][j] = B[i];
else
Xi[i][j] = A[i][j];
// Obliczamy niewiadomą:
X[k] = det(n,Xi) / detA;
}
// Wyświetlamy wyniki:
for(i = 0; i < n; i++)
cout << "x" << i << " = "
<< setw(12)
<< X[i] << endl;
// Usuwamy tablicę
// dynamiczną:
delete [] X;
}
cout << endl;
for(i = 0; i < n; i++)
{
delete [] A[i];
delete [] Xi[i];
}
delete [] A;
delete [] Xi;
delete [] B;
system("pause");
return 0;
}
|
| Wynik |
| Rozwiązywanie układu równań liniowych
wzorami Cramera ----------------------------------------------------- Wpisz dane wejściowe: 5 -1 2 -3 3 5 8 0 7 4 -1 -3 4 -3 2 -2 8 -3 -2 1 2 -2 -1 -6 9 0 56 62 -10 14 28 x0 = 1.00000 x1 = 3.00000 x2 = 5.00000 x3 = 7.00000 x4 = 9.00000 |
Python
(dodatek) # Wzory Cramera
# (C)2026 mgr Jerzy Wałaszek
# Metody numeryczne 0066
#---------------------------
EPS = 0.000000001
# Funkcja oblicza wartość
# wyznacznika macierzy
# metodą rozkładu LU
# z piwotowaniem
# n - stopień macierzy
# A - wskaźnik macierzy
#----------------------
def det(n,a):
# Mnożnik korekcyjny
# dla wyznacznika
md = 1
# Tworzymy wektor wierszowy
w = [i for i in range(n)]
# Rozkład LU
for k in range(n):
# numer wiersza
# z elementem max
maxw = k
maxe = abs(a[w[k]][k])
# Szukamy elementu max
for i in range(k + 1, n):
if abs(a[w[i]][k]) > maxe:
maxw = i
maxe = abs(a[w[i]][k])
# Jeśli max jest zero,
# to macierz jest
# zdegenerowana
if(maxe <= EPS):
return 0
# Jeśli max nie leży
# na przekątnej,
# zamieniamy wiersze
if maxw != k:
# Modyfikujemy mnożnik
md = -md
w[k], w[maxw] = w[maxw], w[k]
# Dzielnik
akk = a[w[k]][k]
# Normalizujemy kolumnę
for i in range(k + 1, n):
a[w[i]][k] /= akk
# Modyfikujemy podmacierz
for i in range(k + 1, n):
for j in range(k + 1, n):
a[w[i]][j] -= (a[w[i]][k]
* a[w[k]][j])
# Obliczamy wyznacznik
sc = md
for k in range(n):
sc *= a[w[k]][k]
return sc
# Program główny
#---------------
print("Rozwiązywanie układu "
"równań liniowych "
"wzorami Cramera\n"
"---------------------"
"-----------------"
"---------------\n\n"
"Wpisz dane wejściowe:\n")
n = int(input())
# Tworzymy dynamicznie
# potrzebne macierze
# Odczytujemy współczynniki
# tworząc z nich macierze
a = [[float(s) for s in input().split()]
for _ in range(n)]
xi = [s[:] for s in a]
# Odczytujemy wyrazy wolne
b = [float(s) for s in input().split()]
print()
# Rozpoczynamy od obliczenia
# wyznacznika macierzy A
det_a = det(n,xi)
if abs(det_a) < EPS:
print("Układ równań bez rozwiązania")
else:
# Tworzymy macierz rozwiąń
x = [0.0 for _ in range(n)]
# Rozpoczynamy wyliczanie
# niewiadomych
for k in range(n):
# Ustawiamy macierz
# pomocniczą Xi
for i in range(n):
for j in range(n):
if j == k:
xi[i][j] = b[i]
else:
xi[i][j] = a[i][j];
# Obliczamy niewiadomą:
x[k] = det(n,xi) / det_a
# Wyświetlamy wyniki:
for i in range(n):
print(f"x{i} = {x[i]:12.5f}")
print()
input("Naciśnij Enter...")
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.