Metoda Cramera


Tematy pokrewne

 

Algorytm

Mamy dany układ n równań liniowych z n niewiadomymi. Zapiszmy go następująco:


a1,1x1  +  a1,2x2  +  a1,3x3  +    ...    +  a1,n-1xn-1  +  a1,nxn  =  b1
a2,1x1  +  a2,2x2  +  a2,3x3  +    ...    +  a2,n-1xn-1  +  a2,nxn  =  b2
a3,1x1  +  a3,2x2  +  a3,3x3  +    ...    +  a3,n-1xn-1  +  a3,nxn  =  b3
...  +  ...  +  ...  +  ...  +  ...  +  ...  =  ...
an-1,1x1  +  an-1,2x2  +  an-1,3x3  +    ...    +  an-1,n-1xn-1  +  an-1,nxn  =  bn-1
an,1x1  +  an,2x2  +  an,3x3  +    ...    +  an,n-1xn-1  +  an,nxn  =  bn


Następnie utwórzmy macierz A współczynników ai,j tego układu równań oraz wektor kolumnowy B wyrazów bi:


A =     a1,1 a1,2 a1,3   ...   a1,n-1 a1,n        B =    b1   
a2,1 a2,2 a2,3   ...   a2,n-1 a2,n b2
a3,1 a3,2 a3,3   ...   a3,n-1 a3,n b3
... ... ... ... ... ... ...
an-1,1  an-1,2  an-1,3    ...   an-1,n-1  an-1,n bn-1
an,1 an,2 an,3   ...   an,n-1 an,n bn


Macierz A jest macierzą kwadratową o wymiarze n x n. Niech W = det A. Jeśli wyznacznik W jest różny od 0 (pamiętajmy o błędach zaokrągleń - sprawdzamy, czy wyznacznik W leży w otoczeniu ε wartości 0), to układ równań posiada rozwiązania. W przeciwnym razie układ równań jest sprzeczny lub liniowo zależny i nie posiada jednoznacznego rozwiązania.

Aby znaleźć wartości kolejnych niewiadomych, postępujemy następująco:

W macierzy A współczynników dla każdej niewiadomej xi , i = 1, 2, ... , n, zastępujemy i-tą kolumnę wektorem kolumnowym B. Następnie wyliczamy wyznacznik Wi tak zmodyfikowanej macierzy. Wartość kolejnych niewiadomych xi , i = 1, 2, ... , n, otrzymamy za pomocą poniższego wzoru:


xi =  Wi
W


Metoda ta nosi nazwę wzorów Cramera (ang. Cramer's Rule).

 

Przykład:

Rozwiążemy przy pomocy podanych powyżej wzorów Cramera układ 3 równań liniowych z trzema niewiadomymi x1, x2 i x3:


3x1 + 2x2 - 3x3 = -2
4x1 - 3x2 + 2x3 = 4
8x1 + 2x2 + 2x3 = 18

 

Najpierw tworzymy macierz A współczynników oraz wektor kolumnowy B:


A =       3    2   -3        B =    -2   
 4  -3  2 4
 8  2  2 18


Wykorzystując regułę Sarrusa obliczamy wyznacznik główny W:


3 2 -3  3 2  = 3×(-3)×2 + 2×2×8 + (-3)×4×2 - (-3)×(-3)×8 - 3×2×2 - 2×4×2 = -110 = W
4 -3 2 4 -3
8 2 2 8 2


Teraz dla niewiadomej x1 w macierzy A zastępujemy kolumnę 1 wektorem B i obliczamy jej wyznacznik W1:


A1 =     -2    2   -3   
4  -3  2
18  2  2

 

-2 2 -3  -2 2  = (-2)×(-3)×2 + 2×2×18 + (-3)×4×2 - (-3)×(-3)×18 - (-2)×2×2 - 2×4×2 = -110 = W1
4 -3 2 4 -3
18 2 2 18 2


Podobnie postępujemy dla pozostałych niewiadomych:


A2 =       3   -2   -3   
 4 4  2
 8 18  2

 

  3  -2  -3   3  -2  = 3×4×2 + (-2)×2×8 + (-3)×4×18 - (-3)×4×8 - 3×2×18 - (-2)×4×2 = -220 = W2
 4 4  2  4 4
 8 18  2  8 18

 

A3 =       3    2   -2   
 4  -3 4
 8  2 18

 
  3    2   -2   3    2  = 3×(-3)×18 + 2×4×8 + (-2)×4×2 - (-2)×(-3)×8 - 3×4×2 - 2×4×18 = -330 = W3
 4  -3 4  4  -3
 8  2 18  8  2

 

Podsumujmy otrzymane wyniki:


W = -110
W1 = -110
W2 = -220
W3 = -330


Zgodnie z wzorami Cramera mamy:

 

x1 =  W1  =  -110  = 1
W -110
x2 =  W2 = -220  = 2
W -110
x3 =  W3 = -330  = 3
W -110

 

Technicznie macierz A współczynników oraz wektor kolumnowy B będziemy przechowywać w jednej tablicy o n wierszach i n+1 kolumnach. Współczynniki przy niewiadomych umieścimy w kolumnach od 1 do n, natomiast n+1 kolumnę zajmą wyrazy wolne bi. Do funkcji obliczającej wyznacznik będziemy przekazywali wektor kolumnowy, w którym po prostu na i-tej kolumnie wpiszemy n+1, czyli numer kolumny z wektorem B. Będzie to odpowiadało zastąpieniu danej kolumny współczynników  wyrazami z kolumny n+1.

 

AB =     1 2 3 ... n-1 n n+1   
  a1,1 a1,2 a1,3   ...   a1,n-1 a1,n b1  
a2,1 a2,2 a2,3   ...   a2,n-1 a2,n b2
a3,1 a3,2 a3,3   ...   a3,n-1 a3,n b3
... ... ... ... ... ... ...
an-1,1  an-1,2  an-1,3    ...   an-1,n-1  an-1,n  bn-1
an,1 an,2 an,3   ...   an,n-1 an,n bn

 

Dane wejściowe

n - ilość niewiadomych oraz układów równań. n N, n < 9
AB[ ] - tablica n(n+1) elementowa zawierająca współczynniki ai,j oraz wyrazy wolne biai,j,bi R; i,j N,  i,j = 1,2,...,n

Dane wyjściowe

X[ ] - tablica n elementowa zawierająca wartości kolejnych niewiadomych xi. xi R , i N , i = 1,2,...,n, lub informacja, iż dany układ równań nie posiada jednoznacznego rozwiązania.

Zmienne pomocnicze i funkcje

det(stopień,wiersz,wektorkolumn[], macierz[]) - funkcja wyliczająca odpowiedni wyznacznik
W - wyznacznikiem główny układu równań.
WK[ ] - wektor kolumn zawierający numery kolumn tablicy AB[ ]. Wykorzystywany jest do podmiany kolumny z wyrazami wolnymi bi w miejsce kolumny współczynników dla odpowiedniej zmiennej.
i - zmienna sterująca pętli,  i N
ε - określa dokładność porównania z zerem. ε = 0.0000000001

 

Lista kroków

  K01: Dla i = 1, 2, ..., nwykonuj WK[i] ← i
  K02: W ← det(n, 1, WK[ ])
  K03: Jeśli | W | < ε , to pisz "Brak rozwiązania" i zakończ
  K04: Dla i = 1, 2, ..., n: wykonuj K05...K07
K05:     WK[i] n + 1
K06:     X[i] det(n,1,WK[ ], AB[ ])
K07:     WK[i] i
  K08: Zakończ

 

Schemat blokowy

Algorytm rozpoczynamy od ustawienia wektora kolumn WK[ ] w pętli nr 1.

Następnie obliczamy wyznacznik macierzy współczynników aij. Wartość wyznacznika zapamiętujemy w zmiennej W.

Jeśli wyznacznik główny W wpada w otoczenie zera o promieniu ε, to układ równań nie posiada jednoznacznego rozwiązania. Wypisujemy odpowiednią informację i kończymy algorytm.

W przeciwnym razie rozwiązanie istnieje. W pętli nr 2 podmieniamy kolejno i-tą kolumnę macierzy współczynników aij przez wektor wyrazów wolnych bi. Podmiana polega na wpisaniu na pozycji i-tej numeru kolumny wyrazów bi, który wynosi n+1. Po tej operacji wywołujemy funkcję obliczającą wyznacznik, jej rezultat dzielimy przez wyznacznik główny W i wynik wprowadzamy na pozycję i-tą do tablicy niewiadomych X[ ]. W wektorze kolumn WK[ ] przywracamy z powrotem podmienioną wcześniej i-tą kolumnę.

Po zakończeniu pętli nr 2 w tablicy X[ ] umieszczone są kolejne wartości niewiadomych xi rozwiązanego układu równań. Możemy je dowolnie wykorzystać. Algorytm kończymy.


 

Programy

Prezentowane poniżej przykładowe programy odczytują dane z pliku in.txt i zapisują wyniki do pliku out.txt. Przyjęliśmy to rozwiązanie z uwagi na dużą liczbę danych, które muszą być dostarczone do programu - klawiatura nie byłaby zbyt wygodna. Pliki znajdują się w bieżącym katalogu. Plik in.txt powinien posiadać następującą strukturę:

W pierwszym wierszu liczba od 1 do 8 (ważne, gdyż z uwagi na czasochłonność obliczeń ograniczyłem maksymalny rozmiar macierzy do przechowania maksymalnie 8 równań) określająca ilość równań, czyli n.

W następnych n wierszach powinny być umieszczone współczynniki. Jeden wiersz określa współczynniki jednego równania. Kolejne współczynniki powinny być od siebie oddzielone przynajmniej jedną spacją. Pierwsze n współczynników odnosi się do współczynników przy kolejnych niewiadomych. Ostatni (n+1)-szy współczynnik określa wyraz wolny bi. Programy uruchomiono z plikiem in.txt o następującej zawartości:

 

5
2 -2  2 -7  6 -4
7 -3 -2  7  2 11
2  2 -1  1  4  9
9  8 -2  2 -2 21
4  8 -3  3 -1 16

 

Plik określa układ 5 równań liniowych:

 

2x1 - 2x2  +  2x3 - 7x4  +  6x5 =   -4
7x1 - 3x2 - 2x3  +  7x4  +  2x5  =  11
2x1  +  2x2 - x3  +  x4  +  4x5  =    9
9x1  +  8x2 - 2x3  +  2x4 - 2x5  =  21
4x1  +  8x2 - 3x3  +  3x4 - x5  =  16

 

Efekt uruchomienia programu
Demonstracja rozwiązywania układu równań metodą Cramera
-------------------------------------------------------
(C)2006 mgr Jerzy Wałaszek              I LO w Tarnowie

 2,00*x1 -  2,00*x2 +  2,00*x3 -  7,00*x4 +  6,00*x5 = -4,00
 7,00*x1 -  3,00*x2 -  2,00*x3 +  7,00*x4 +  2,00*x5 = 11,00
 2,00*x1 +  2,00*x2 -  1,00*x3 +  1,00*x4 +  4,00*x5 =  9,00
 9,00*x1 +  8,00*x2 -  2,00*x3 +  2,00*x4 -  2,00*x5 = 21,00
 4,00*x1 +  8,00*x2 -  3,00*x3 +  3,00*x4 -  1,00*x5 = 16,00

-------------------------------------------------------
Wyniki:

x0 =      1,00000
x1 =      2,00000
x2 =      3,00000
x3 =      2,00000
x4 =      1,00000

-------------------------------------------------------
Koniec. Naciśnij klawisz Enter...

 

Free Pascal
// Program rozwiązuje układ równań liniowych o n niewiadomych
// za pomocą metody wyznacznikowej Cramera. n <= 8
//-----------------------------------------------------------
// (C)2006 mgr J.Wałaszek                     I LO w Tarnowie

program mzfl4;

{$APPTYPE CONSOLE}

const
  EPS = 0.0000000001; // dokładność porównania z zerem

type
  kwektor = array[1..8] of integer;
  macierz = array[1..8,1..9] of double;

// Rekurencyjna funkcja obliczania wyznacznika
//--------------------------------------------

function det(stopien, wiersz : integer;
             var wk : kwektor;
             var A  : macierz) : extended;
var
  i,j,k,m : integer;
  kolumny : kwektor; // wektor kolumn dla podmacierzy
begin
  if stopien = 1 then
    Result := A[wiersz,wk[1]]
  else
  begin
    Result := 0; m := 1;
    for i := 1 to stopien do
    begin
      k := 1;
      for j := 1 to stopien - 1 do
      begin
        if k = i then inc(k);
        kolumny[j] := wk[k];
        inc(k);
      end;
      Result := Result+m*A[wiersz,wk[i]]*det(stopien-1,wiersz+1,kolumny,A);
      m := -m;
    end;
  end;
end;

//-----------------------------------------------------
// Program główny
//-----------------------------------------------------

var
  f     : Text;
  i,j,n : integer;
  AB    : macierz;
  W     : extended;
  X     : array[1..8] of double;
  WK    : kwektor;
begin
  writeln('Demonstracja rozwiazywania ukladu rownan metoda Cramera');
  writeln('-------------------------------------------------------');
  writeln('(C)2006 mgr Jerzy Walaszek              I LO w Tarnowie');
  writeln;

// Dane dla programu odczytujemy z pliku tekstowego o nazwie in.txt,
// który musi się znajdować w tym samym katalogu co program
// Pierwszy wiersz pliku powinien zawierać liczbę n
// Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
// tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
// oddzielone są od siebie przynajmniej jedną spacją.

  assignfile(f,'in.txt');
  reset(f);
  readln(f,n);
  if n <= 8 then
  begin
    for i := 1 to n do
      for j := 1 to n + 1 do read(f,AB[i,j]);
    closefile(f);

// Wyświetlamy wczytany układ równań w oknie konsoli

    for i := 1 to n do
      for j := 1 to n + 1 do
      begin
        if j = 1 then write(AB[i,j]:5:2)
        else if j = n + 1 then writeln('= ',AB[i,j]:5:2)
        else
        begin
          if AB[i,j] > 0 then
              write('+',AB[i,j]:5:2)
            else
              write('-',abs(AB[i,j]):5:2);
        end;
        if j <= n then write('*x',j,' ');
      end;
    writeln;
    writeln('-------------------------------------------------------');
    writeln('Wyniki:');
    writeln;

// Otwieramy plik wyników out.txt

    assignfile(f,'out.txt');
    rewrite(f);

// Obliczamy wyznacznik główny

    for i := 1 to n do WK[i] := i;
    W := det(n,1,WK,AB);
    if abs(W) < EPS then
      writeln('Brak rozwiazania')
    else
    begin

// Obliczamy kolejne wyznaczniki Wi

      for i := 1 to n do
      begin
        WK[i] := n + 1;       // podmieniamy kolumnę współczynnikami bi
        X[i]  := det(n,1,WK,AB) / W;
        WK[i] := i            // przywracamy kolumnę współczynników ai
      end;

// Wypisujemy wyniki do okna konsoli oraz do pliku out.txt

      for i := 1 to n do
      begin
        writeln('x',i,' = ',X[i]:10:5);
        writeln(f,X[i]);
      end;
    end;
  end
  else writeln('Za wiele rownan!');
  closefile(f);
  writeln;
  writeln('-------------------------------------------------------');
  writeln('Koniec. Nacisnij klawisz Enter...');
  readln;
end.
Code::Blocks
// Program rozwiązuje układ równań liniowych o n niewiadomych
// za pomocą metody wyznacznikowej Cramera. n <= 8
//-----------------------------------------------------------
// (C)2006 mgr J.Wałaszek                     I LO w Tarnowie

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <cstdlib>

using namespace std;

// Rekurencyjna funkcja obliczania wyznacznika
//--------------------------------------------

long double det(int stopien, int wiersz, int wk[], double A[][9])
{
  int i,j,k,m;
  int kolumny[8]; // wektor kolumn dla podmacierzy
  long double suma;

  if(stopien == 1)
    return A[wiersz][wk[0]];
  else
  {
    suma = 0; m = 1;
    for(i = 0; i < stopien; i++)
    {
      k = 0;
      for(j = 0; j < stopien - 1; j++)
      {
        if(k == i) k++;
        kolumny[j] = wk[k++];
      }
      suma += m * A[wiersz][wk[i]] * det(stopien - 1, wiersz + 1, kolumny, A);
      m = -m;
    }
  return suma;
  }
}

//-----------------------------------------------------
// Program główny
//-----------------------------------------------------

int main()
{
  const double EPS = 0.0000000001; // dokładność porównania z zerem
  ifstream fin;
  ofstream fout;
  int i,j,n,WK[8];
  double AB[8][9],X[8];
  long double W;

  cout << setprecision(2)     // 2 cyfry po przecinku
       << fixed;              // format stałoprzecinkowy

  cout << "Demonstracja rozwiazywania ukladu rownan metoda Cramera\n"
          "-------------------------------------------------------\n"
          "(C)2006 mgr Jerzy Walaszek              I LO w Tarnowie\n\n";

// Dane dla programu odczytujemy z pliku tekstowego o nazwie in.txt,
// który musi się znajdować w tym samym katalogu co program
// Pierwszy wiersz pliku powinien zawierać liczbę n
// Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
// tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
// oddzielone są od siebie przynajmniej jedną spacją.

  fin.open("in.txt");
  fin >> n;
  if(n <= 8)
  {
    for(i = 0; i < n; i++)
      for(j = 0; j <= n; j++) fin >> AB[i][j];
    fin.close();

// Wyświetlamy wczytany układ równań w oknie konsoli

    for(i = 0; i < n; i++)
      for(j = 0; j <= n; j++)
      {
        if(!j) cout << setw(5) << AB[i][j];
        else if(j == n) cout << "= " << setw(5) << AB[i][j] << endl;
        else
        {
          if(AB[i][j] > 0)
            cout << "+" << setw(5) << AB[i][j];
          else
            cout << "-" << setw(5) << fabs(AB[i][j]);
        }
        if(j < n) cout << "*x" << j + 1 << " ";
      }
    cout << "\n-------------------------------------------------------\n"
            "Wyniki:\n\n";

// Otwieramy plik wyników out.txt

    fout.open("out.txt");

// Obliczamy wyznacznik główny

    for(i = 0; i < n; i++) WK[i] = i;
    W = det(n,0,WK,AB);
    if(fabs(W) < EPS)
      cout << "Brak rozwiazania\n";
    else
    {

// Obliczamy kolejne wyznaczniki Wi

      for(i = 0; i < n; i++)
      {
        WK[i] = n; // podmieniamy kolumnę współczynnikami bi
        X[i]  = det(n,0,WK,AB) / W;
        WK[i] = i; // przywracamy kolumnę współczynników ai
      }

// Wypisujemy wyniki do okna konsoli oraz do pliku out.txt

      for(i = 0; i < n; i++)
      {
        cout << "x" << i + 1 << " = " << setw(10) << X[i] << endl;
        fout << X[i] << endl;
      }
      fout.close();
    }
  }
  else
  {
    fin.close();
    cout << "Zbyt wiele rownan!\n";
  }
  cout << "\n-------------------------------------------------------\n\n";
  system("pause");
  return 0;
}
FreeBASIC
' Program rozwiązuje układ równań liniowych o n niewiadomych
' za pomocą metody wyznacznikowej Cramera. n <= 8
'-----------------------------------------------------------
' (C)2006 mgr J.Wałaszek                     I LO w Tarnowie

Declare Function det(stopien As Integer, wiersz As Integer, wk() As Integer, A() As Double) As Double

const EPS As Double = 0.0000000001 ' dokładność porównania z zerem

'-----------------------------------------------------
' Program główny
'-----------------------------------------------------

Dim As Integer i,j,n,WK(7)
Dim As double AB(7,8),X(7),W

Print "Demonstracja rozwiazywania ukladu rownan metoda Cramera"
Print "-------------------------------------------------------"
Print "(C)2006 mgr Jerzy Walaszek              I LO w Tarnowie"
Print

' Dane dla programu odczytujemy z pliku tekstowego o nazwie in.txt,
' który musi się znajdować w tym samym katalogu co program
' Pierwszy wiersz pliku powinien zawierać liczbę n
' Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
' tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
' oddzielone są od siebie przynajmniej jedną spacją.

Open "in.txt" For Input As #1
Input #1,n
if n <= 8 Then
  For i = 0 to n - 1
    for j = 0 to n: Input #1, AB(i,j): Next
  Next

  ' Wyświetlamy wczytany układ równań w oknie konsoli

  for i = 0 to n - 1
    for j = 0 to n
      if j = 0 Then
      	print Using "##.##";AB(i,j);
      ElseIf j = n Then
        Print Using " = ##.##";AB(i,j)
      Else
        Print Using " +##.##";AB(i,j);
      End If
      if j < n then Print Using "*X#";j+1;
    Next
  Next
  Print
  Print "-------------------------------------------------------"
  Print "Wyniki:"
  Print

' Otwieramy plik wyników out.txt

  Open "out.txt" For Output As #2

' Obliczamy wyznacznik główny

  for i = 0 to n-1: WK(i) = i: Next
  W = det(n,0,WK(),AB())
  if abs(W) < EPS then
    Print #2,"Brak rozwiazania"
    Print "Brak rozwiazania"
  Else
 
    ' Obliczamy kolejne wyznaczniki Wi

    for i = 0 to n - 1
      WK(i) = n               ' podmieniamy kolumnę współczynnikami bi
      X(i)  = det(n,0,WK(),AB()) / W
      WK(i) = i               ' przywracamy kolumnę współczynników ai
    Next

' Wypisujemy wyniki do okna konsoli oraz do pliku out.txt

    for i = 0 to n - 1
      print #2,Using "x# = ####.#####";i;X(i)
      print Using "x# = ####.#####";i;X(i)
    Next
    Close #2
  End If
Else
  Print "Za wiele rownan!"
End If
Close #1
Print
Print "-------------------------------------------------------"
Print "Koniec. Nacisnij klawisz Enter..."
Sleep
End

' Rekurencyjna funkcja obliczania wyznacznika
'--------------------------------------------

Function det(stopien As Integer, wiersz As Integer, wk() As Integer, A() As Double) As Double
    Dim As Integer i, j, k, m
    Dim kolumny(7) As Integer ' wektor kolumn dla podmacierzy
    Dim suma As Double

    If stopien = 1 Then
      return A(wiersz, wk(0))
    Else
      suma = 0 : m = 1
      For i = 0 To stopien - 1
        k = 0
        For j = 0 To stopien - 2
          If k = i Then k += 1
          kolumny(j) = wk(k)
          k += 1
        Next
        suma += m * A(wiersz, wk(i)) * det(stopien - 1, wiersz + 1, kolumny(), A())
        m = -m
      Next
      Return suma
    End If
  End Function

 

Program w JavaScript pobiera dane z okna tekstowego. Spowodowane jest to tym, iż w JavaScript dostęp do plików komputera użytkownika jest ograniczony - przecież nie chciałbyś, aby jakaś strona WWW buszowała po dysku twardym twojego komputera - byłby to raj dla hackerów.

Dane dla układu równań możesz wkleić poprzez schowek do okna tekstowego formularza.

 

JavaScript
<html>
  <head>
  </head>
  <body>
    <div align="center">
      <form style="BORDER-RIGHT: #ff9933 1px outset; PADDING-RIGHT: 4px;
                   BORDER-TOP: #ff9933 1px outset; PADDING-LEFT: 4px;
                   PADDING-BOTTOM: 1px; BORDER-LEFT: #ff9933 1px outset;
                   PADDING-TOP: 1px; BORDER-BOTTOM: #ff9933 1px outset;
                   BACKGROUND-COLOR: #ffcc66" name="frmbincode">
        <h3 style="TEXT-ALIGN: center">
          Demonstracja rozwiązywania układu równań<br>
          metodą Cramera
        </h3>
        <p style="TEXT-ALIGN: center">
          (C)2006 mgr Jerzy Wałaszek I LO w Tarnowie
        </p>
        <hr>
        <p style="TEXT-ALIGN: center">
          Tutaj wprowadź wiersze ze współczynnikami układu równań:
        </p>
        <p style="TEXT-ALIGN: center">
          <textarea rows="9" name="input" cols="70">5
2 -2 2 -7 6 -4
7 -3 -2 7 2 11
2 2 -1 1 4 9
9 8 -2 2 -2 21
4 8 -3 3 -1 16</textarea>
        </p>
        <p style="TEXT-ALIGN: center">
          <input type="button" value="Rozwiąż układ równań" name="B1"
                 onclick="main()">
        </p>
        <div id="out" align=center>...</div>
      </form>

<script language=javascript>

// Program rozwiązuje układ równań liniowych o n niewiadomych
// za pomocą metody wyznacznikowej Cramera. n <= 8
//-----------------------------------------------------------
// (C)2006 mgr J.Wałaszek I LO w Tarnowie

// Rekurencyjna funkcja obliczania wyznacznika
//--------------------------------------------

function det(stopien, wiersz, wk, A)
{
  var i,j,k,m;
  var kolumny = new Array(8); // wektor kolumn dla podmacierzy
  var suma;

  if(stopien == 1)
    return A[wiersz][wk[0]];
  else
  {
    suma = 0; m = 1;
    for(i = 0; i < stopien; i++)
    {
      k = 0;
      for(j = 0; j < stopien - 1; j++)
      {
        if(k == i) k++;
        kolumny[j] = wk[k++];
      }
      suma += m * A[wiersz][wk[i]] * det(stopien - 1, wiersz + 1, kolumny, A);
      m = -m;
    }
    return suma;
  }
}

//-----------------------------------------------------
// Program główny
//-----------------------------------------------------

function main()
{
  var EPS = 0.0000000001; // dokładność porównania z zerem
  var i,j,k,n,W,t,s,z;
  var WK = new Array(8);
  var AB = new Array(8);
  var X =  new Array(8);

// Dane dla programu odczytujemy z pola tekstowego.
// Pierwszy wiersz pola powinien zawierać liczbę n
// Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
// tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
// oddzielone są od siebie przynajmniej jedną spacją.

  t = "<font color=red><b>Złe dane</b></font>";
  s = document.frmbincode.input.value;
  if(s.length > 0)
  {

// Odczytujemy współczynniki z pola tekstowego formularza

    while((j = s.indexOf('\n')) != -1)
      s = s.substring(0,j) + " " + s.substring(j + 1,s.length);
    while((j = s.indexOf('\r')) != -1)
      s = s.substring(0,j) + " " + s.substring(j + 1,s.length);
    while((j = s.indexOf('\t')) != -1)
      s = s.substring(0,j) + " " + s.substring(j + 1,s.length);
    while(s.length > 0 && (s.charAt(0) == " "))
      s = s.substring(1,s.length);
    while(s.length > 0 && (s.charAt(s.length-1) == " "))
      s = s.substring(0,s.length - 1);
    while(s.length > 0 && ((j = s.indexOf("  ")) != -1))
      s = s.substring(0,j) + s.substring(j+1,s.length);
    s = s.split(' ');
    if(s.length > 0)
    {
      n = parseInt(s[0]);
      if((!isNaN(n)) && (s.length >= n * (n + 1) + 1) && (n <= MAXEQ))
      {
        k = 1; z = true;
        for(i = 0; i < n; i++)
        {
          AB[i] = new Array(n + 1);
          for(j = 0; j <= n; j++)
            z = z && !isNaN(AB[i][j] = parseFloat(s[k++]));
        }
        if(z)
        {

// Wyświetlamy układ równań

t = "<table border='0' cellpadding='4' style='border-collapse: collapse'><tr><td>";

          for(i = 0; i < n; i++)
          {
            for(j = 0; j <= n; j++)
            {
              if(!j) t += AB[i][j];
              else if (j == n) t += " = " + AB[i][j];
              else
                t += (AB[i][j] < 0) ? " - " + Math.abs(AB[i][j]) : " + " + AB[i][j];
              if(j < n) t += "x<sub>" + (j + 1) + "</sub>";
            }
            t += "<br>";
          } 
          t += "</td></tr><tr><td>";

// Obliczamy wyznacznik główny

          for(i = 0; i < n; i++) WK[i] = i;
          W = det(n, 0, WK, AB);
          if(Math.abs(W) < EPS)
            t += "<font color=red><b>Brak rozwiazania</b></font>";
          else
          {

// Obliczamy kolejne wyznaczniki Wi

            for(i = 0; i < n; i++)
            {
              WK[i] = n; // podmieniamy kolumnę współczynnikami bi
              X[i] = det(n, 0, WK, AB) / W;
              WK[i] = i; // przywracamy kolumnę współczynników ai
            }

// Wypisujemy wyniki

            for(i = 0; i < n; i++)
              t += "x<sub>" + (i + 1) + "</sub> = " + X[i] + "<br>";
            t += "</td></tr></table>";
          } 
        }
      }
    }
  }
  document.getElementById("out").innerHTML = t;
}

</script>
    </div>
  </body>
</html>

 

Tutaj możesz przetestować działanie prezentowanego skryptu.

Demonstracja rozwiązywania układu równań
metodą Cramera

(C)2006 mgr Jerzy Wałaszek I LO w Tarnowie


Tutaj wprowadź wiersze ze współczynnikami układu równań:


...


List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.