Rozwiązywanie układów równań liniowych.

Deti

Układy równań liniowych to takie, które mogą mieć

  • jedno rozwiązanie
  • nieskończenie wiele rozwiązań
  • brak rozwiązania (układ sprzeczny).

A oto typowy przykład układu równań z trzema równaniami i trzema niewiadomymi.

5x+3y+5z=8 3x+7y-z=0 -10x-7y+z=15

Taki układ (gdzie liczba niewiadomych jest równa liczbie równań) da się zazwyczaj rozwiązać. Jeżeli liczba równań jest większa: układ może już być sprzeczny. Jeżeli mniejsza: układ nie ma rozwiązania. My tutaj będziemy się zajmować układami gdzie ilość równań jest równa ilości niewiadomych. Są to tzw. układy Cramera.

Pierwsza rzecz to taka sprawa, że jeżeli w dowolnym równaniu przestawimy dowolnie wyrażenia, układ cały się nie zmieni. Czyli można dowolny układ przekształcić tak, aby kolumny były z tą samą niewiadomą (tzn. pierwsza kolumna z „x”-ami, druga z „y”-kami itd.). Jeżeli dana niewiadoma nie występuje w jakimś równaniu, piszemy jej współczynnik jako „0”.

To teraz jak rozwiązać prosty układ liniowy. Pokaże wam jak to zrobić dla dwóch i trzech zmiennych (równań). Sami sobie już zrobicie graficzną „oprawę”. Ja tylko podam wam nazwy zmiennych. No to zaczynamy.

Układ równań z dwoma niewiadomymi.

A wygląda on tak:

ax + by = c
dx + ey = f

Zmienne a,b,c,d,e oraz f to dowolne zmienne liczbowe. Gdy już dane te zostaną załadowane, można zrobić taką oto procedurę:

<font color="blue"> IF (a*e – b*d) <0 THEN BEGIN X:= (c*e – b*f) / (a*e – b*d); Y:= (a*f – c*d) / ( a*e – b*d); END; </font color>

No i mamy układ rozwiązany. Jeżeli natomiast wartość „ae – bd” jest równa 0, układ ten nie ma rozwiązania. Można sobie samemu już dopisać ELSE.

Układ równań z trzema niewiadomymi.

To teraz trochę bardziej skomplikowana sprawa:

ax + by + cz = d
e
x + fy + g+z = h
i
x + jy + kz = l

Procedura jest już podobna, aczkolwiek bardziej skomplikowana:

<font color="blue"> IF (a*f*k) + (b*g*i) + (c*e*j) – (c*f*i) – (a*g*j) – (b*e*k) <0 THEN BEGIN

X:= ((dfk) + (bgl) + (chj) – (cfl) – (dgj) – (bhk)) / ((afk) + (bgi) + (cej) – (cfi) – (agj) – (bek));

Y:= ((ahk) + (dgi) + (cel) – (chi) – (cgl) – (dek)) / ((afk) + (bgi) + (cej) – (cfi) – (agj) – (bek));

Z:=((afl) + (bhi) + (dej) – (dfi) – (ahj) – (bel)) / ((afk) + (bgi) + (cej) – (cfi) – (agj) – (bek));

END;
</font color>

Tutaj tak samo można sformułować polecenie ELSE, jeżeli w/w warunek nie będzie spełniony.

Dla układów równań o większej liczbie niewiadomych, obliczenia te stają się horrendalnie długie. Powyższe sposoby rozwiązania mają bardzo istotną cechę: wyszukują każde rozwiązanie, nie tylko całkowite.

11 komentarzy

a czy ktoś wie jak zrobić w rozwiązywaniu dwóch układów z dwoma niewiadomymi żeby program stwierddzał czy jest prosta prostopadła równoległa czy skośna

Nadzwyczajnie bozia nie obdarzyła zdolnością formatowania tekstu :>

Mój program, bardzo dobry i krótki. Eliminacja Gaussa (macierz górnotrójkątna):

program n_rownan_z_n_niewiadomymi;

{$APPTYPE CONSOLE}

uses
SysUtils;

const
nmax=10;

var
x,b:array[1..nmax] of extended;
A:array[1..nmax,1..nmax] of extended;
n,z,w,k,gw:integer;
m,d,s:extended; // n - rozmiar macierzy
// w - liczba wierszy
// k - liczba kolumn
// gw - liczba kolejejnych krokow wyzerowan kolumn
// m - mnoznik
// d - mnozenie wspol*x
// s -suma wspol.*x

begin
{ TODO -oUser -cConsole Main : Insert code here }

writeln('Program do rozwiazywania rownania macierzowego A*x=b metoda Gaussa !!!');

// 1.Podac wymiar macierzy do n = 10 -> (n)
write('Podaj wymiar macierzy A: ');
readln(n);
writeln;

// 2.Podac dokladnosc zaokraglnia
writeln('Podaj dokladnosc zaokraglania: ');
readln(z);
writeln;

// 3.Podac elementy macierzy A -> akw k=1..n , w=1..n
writeln('Podaj elementy macierzy A: ');
for w:=1 to n do
begin
for k:=1 to n do
begin
write('A[',w,',',k,']: ');
readln(A[w,k]);
end;
end;
writeln;

// 3.Podac elementy wyrazow wolnych b -> bw w=1..n
writeln('Podaj elementy macierzy b: ');
for w:=1 to n do
begin
write('b[',w,']: ');
readln(b[w]);
end;
writeln;

// 5.Doprowadzic maciez [A|b] do postaci gornotrojkatnej metoda eliminacji Gausa (postepowanie proste)
for gw:=1 to n-1 do
begin
for w:=1+gw to n do
begin
m:=A[w,gw]/A[gw,gw];
for k:=gw to n do
begin
A[w,k]:=A[w,k]-ma[gw,k];
end;
b[w]:=b[w]-m
b[gw];
end;
end;

{ // 6. Wyswietlenie macierzy gornotrojkatnej
writeln('Macierz gornotrojkatna [A|b] (eliminacja Gaussa) wyglada tak: ');
for w:=1 to n do
begin
for k:=1 to n do
begin
writeln('A[',w,',',k,'] = ',a[w,k]z);
end;
writeln('b[',w,'] = ',b[w]z);
writeln;
end; }

// 7. Wyznaczyc rozwiazania x -> xw w=n..1
writeln('Rozwiazaniami sa liczby: ');
for w:=n downto 1 do
begin
s:=0;
for k:=w+1 to n do
begin
d:=a[w,k]*x[k];
s:=s+d;
end;
x[w]:=(b[w]-s)/a[w,w];
writeln('x[',w,'] = ',x[w]z);
end;
readln;
end.

uses crt;
const max=20;
type matrix=array[1..max+1,1..max+1]of extended;
vector=array[1..max+1]of extended;
procedure gauss(n: integer; a: matrix;var x:vector);
{ Optymalna szybkosc dzialania }
{ Eliminacja Gaussa wierszami }
var
i, j, k, wm: integer;
p, w, max : extended;
begin
w:= 1;
for i:= 1 to n-1 do
begin
max:= abs (a[i,i]);
wm:= i;
for j:= i+1 to n do { wybor maxymalnego elementu }
if abs (a[j,i]) > max then
begin
max:= abs (a[j,i]);
wm:= j
end;
if wm > i then { zamiana wierszy }
begin
for k:= i to n+1 do
begin
p:= a[i,k];
a[i,k]:= a[wm,k];
a[wm,k]:= p
end;
w:= -w { zamiana wierszy zmienia znak }
end;
if a[i,i] = 0 then { macierz osobliwa }
w:= 0;
if w <> 0 then { eliminacja Gaussa }
for j:= i+1 to n do
begin
p:= a[j,i] / a[i,i];
for k:= n+1 downto i+1 do
a[j,k]:= a[j,k] - p * a[i,k]
end;
w:= w * a[i,i] { iloczyn elementow na przekatnej }
end;
w:= w * a[n,n];
x[n+1]:=w;
if w<>0 then
for i := n downto 1 do
begin
p := A [i,n+1];
for j := i + 1 to n do
p := p - A [i,j] * x [j];
x [i] := p/A[i,i];
end;
end;
var i,j,n:integer;
a:matrix;
x:vector;
ch:char;
begin
clrscr;
repeat
writeln('Obliczanie ukladow rownan.');
writeln;
write('Podaj ilosc rownan n=');
readln(n);
for i:=1 to n do
begin
writeln('Wprowadz ',i,'-te rownanie');
for j:=1 to n+1 do
begin
write('a[',i,',',j,']=');
readln(a[i,j]);
end;
writeln;
end;
writeln;
gauss(n,a,x);
for i:=1 to n+1 do
if i=n+1 then writeln('det(A)=',x[i]6)
else writeln('x[',i,']=',x[i]6);
ch:=readkey;
until ch=#27;
end.
Oto program w Pascal po drobnej modyfikacji będzie dzialał w Delphi

uses crt;
const max=20;
type matrix=array[1..max+1,1..max+1]of extended;
vector=array[1..max+1]of extended;
procedure gauss(n: integer; a: matrix;var x:vector);
{ Optymalna szybkosc dzialania }
{ Eliminacja Gaussa wierszami }
var
i, j, k, wm: integer;
p, w, max : extended;
begin
w:= 1;
for i:= 1 to n-1 do
begin
max:= abs (a[i,i]);
wm:= i;
for j:= i+1 to n do { wybor maxymalnego elementu }
if abs (a[j,i]) > max then
begin
max:= abs (a[j,i]);
wm:= j
end;
if wm > i then { zamiana wierszy }
begin
for k:= i to n+1 do
begin
p:= a[i,k];
a[i,k]:= a[wm,k];
a[wm,k]:= p
end;
w:= -w { zamiana wierszy zmienia znak }
end;
if a[i,i] = 0 then { macierz osobliwa }
w:= 0;
if w <> 0 then { eliminacja Gaussa }
for j:= i+1 to n do
begin
p:= a[j,i] / a[i,i];
for k:= n+1 downto i+1 do
a[j,k]:= a[j,k] - p * a[i,k]
end;
w:= w * a[i,i] { iloczyn elementow na przekatnej }
end;
w:= w * a[n,n];
x[n+1]:=w;
if w<>0 then
for i := n downto 1 do
begin
p := A [i,n+1];
for j := i + 1 to n do
p := p - A [i,j] * x [j];
x [i] := p/A[i,i];
end;
end;
var i,j,n:integer;
a:matrix;
x:vector;
ch:char;
begin
clrscr;
repeat
writeln('Obliczanie ukladow rownan.');
writeln;
write('Podaj ilosc rownan n=');
readln(n);
for i:=1 to n do
begin
writeln('Wprowadz ',i,'-te rownanie');
for j:=1 to n+1 do
begin
write('a[',i,',',j,']=');
readln(a[i,j]);
end;
writeln;
end;
writeln;
gauss(n,a,x);
for i:=1 to n+1 do
if i=n+1 then writeln('det(A)=',x[i]6)
else writeln('x[',i,']=',x[i]6);
ch:=readkey;
until ch=#27;
end.
Oto program w Pascal po drobnej modyfikacji będzie dzialał w Delphi

Ja Kocham układy równań !

Krótko: Nie NAAAWIDZĘ układów równań!!!!

racja racja, ponadto można napisać od razu metode która rozwiązuje układy równań nadliczbowych (normalnych of coz też)

Do macierzy jednostkowej, to rzeczywiście cieżko, ale nam przecież nie potrzebna jest macierz jednostkowa. Wystarczy trójkątna (jak człowiek liczy to wygodniej na jednostkowej, ale dla komputera to pryszcz).
Jak znajdę czas (czyli nie za prędko) to może napiszę gotowca.

Tak, ale jak zmusić komputer do zastosowania odpowiedniego przekształcenia, żeby to miało sens i powstało to co ma powstać. [macierz jednostkowa].

Znacznie bardziej efektywną metodą rozwiązywania układów równań wielu zmiennych jest metoda Gaussa. Dla komputera dzałania na macierzach (zwłaszcza takie proste, jak stosuje się w tej metodzie) jest niesamowicie proste. Co więcej, dla dużych układów metoda Gaussa jest znacznie bardziej efektywna, gdyż nie trzeba wyliczać wyznacznika, który ze względu na dużą ilość operacji mnożenia jest bardzo czasochłonny.