Cześć, mam problem. Napisałem taki o to program rozwiązujący układy równań 4x4:
unit Unit3;
var
Form1: TForm1;
a,b,c,n,i:Integer;
prawo: Integer=1;
gora: Integer=1;
MA: Array of Array of real;
MB, MX: Array of real;
implementation
{$R *.DFM}
procedure zamien(var jeden, dwa: Integer);
var i:Integer;
tmp: Real;
begin
for i:=jeden to n do
begin
tmp:=MA[i,jeden];
MA[i,jeden]:=MA[i,dwa];
MA[i,dwa]:=tmp;
end;
tmp:=MB[jeden];
MB[jeden]:=MB[dwa];
MB[dwa]:=tmp;
end;
procedure OBLICZ(var blad:Byte; x:Integer);
var i,j:Integer;
tmp: Real;
begin
tmp:=0;
for i:=x to n do if tmp<Abs(MA[x,i]) then
begin j:=i; tmp:=Abs(MA[x,i])
end; //wyszukanie największego elementu
if tmp=0 then
begin
blad:=1;
exit;
end;
zamien(x,j); //zamiana wierszy - wybór częściowy elementu podstawowego
for i:=x+1 to n do
begin
tmp:=(MA[i,x]/MA[x,x]);
for j:=x to n do MA[i,j]:=MA[i,j]-tmp*MA[x,j];
MB[i]:=MB[i]-tmp*MB[x];
end;
try
except
ShowMessage('Brak rozwiązania');
end;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
//Zrobienie siatki i ustawienie tablic dynamicznych
var i,j:Integer;
begin
Finalize(MA); Finalize(MB);
n:=4;
StringGrid1.ColCount:=n+2;
StringGrid1.RowCount:=n+1;
SetLength(MA, n+1, n+1);
SetLength(MB, n+1);
SetLength(MX, n+1);
for i:=0 to n+2 do for j:=1 to n+1 do StringGrid1.Cells[i,j]:='';
for i:=1 to n do StringGrid1.Cells[i,0]:='x'+IntToStr(i);
for i:=1 to n do StringGrid1.Cells[0,i]:='rownanie '+IntToStr(i);
StringGrid1.Cells[n+1,0]:='b'
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
begin
if gora>1 then
begin
gora:=gora-1;
StringGrid1.Col:=prawo;
StringGrid1.Row:=gora;
end;
end;
procedure TForm1.BitBtn4Click(Sender: TObject);
begin
if prawo>1 then
begin
prawo:=prawo-1;
StringGrid1.Col:=prawo;
StringGrid1.Row:=gora;
end;
end;
procedure TForm1.BitBtn5Click(Sender: TObject);
begin
if gora<n then
begin
gora:=gora+1;
StringGrid1.Col:=prawo;
StringGrid1.Row:=gora;
end;
end;
procedure TForm1.BitBtn6Click(Sender: TObject);
begin
if prawo<n+1 then
begin
prawo:=prawo+1;
StringGrid1.Col:=prawo;
StringGrid1.Row:=gora;
end;
end;
procedure TForm1.Button3Click(Sender: TObject); // wprowadzenie liczby z Edita do siatki
var i:Integer;
begin
if prawo=n+1 then Val(Edit2.Text,MB[gora],i) Else Val(Edit2.Text,MA[gora,prawo],i);
if i<>0 then ShowMessage('Blad podczas wpisu') Else StringGrid1.Cells[prawo,gora]:=Edit2.Text;
end;
procedure TForm1.Button4Click(Sender: TObject);
var i,j,k:Integer;
suma: Real;
blad: Byte;
begin
blad:=0;
for i:= 1 to n do
for j:=1 to n do
Val(StringGrid1.Cells[i,j],MA[j,i],k);
for i:=1 to n do Val(StringGrid1.Cells[n+1,i],MB[i],k);
for i:=1 to n-1 do
begin
Oblicz(blad, i);
if blad<>0 then break;
end;
begin
Memo1.Clear;
if blad=1 then begin Form1.Memo1.Lines.Add('Układ sprzeczny'); exit; end;
for i:=n downto 1 do
begin
suma:=0;
for j:=i+1 to n do suma:=suma+MA[i,j]*MX[j];
if MA[i,i]=0 then begin Form1.Memo1.Lines.Add('Układ ma nieskończenie wiele rozwiązań'); exit; end;
MX[i]:=(MB[i]-suma)/MA[i,i]
end;
Form1.Memo1.Lines.Add('ROZWIĄZANIE');
if blad=0 then for i:=1 to n do Form1.Memo1.Lines.Add('x'+IntToStr(i)+' = '+FloatToStr(MX[i]));
try
except
ShowMessage('Brak rozwiązania');
end;
end;
end;
end.
Program działa dla nieujemnych liczb, dobrze rozpoznaje też układy sprzeczne. Natomiast jeśli któryś z wprowadzonych współczynników jest ujemny, program nie podaje prawidłowego rozwiązania, np. dla układu sprzecznego:
a -5b - 8c + d = 3
3a +b -3c -5d = 1
a + 0b -7c +2d = -5
0a +11b + 20c -9d=2
podaje wyniki.
Po serii testów doszedłem do tego, że problem tkwi w ujemnych współczynnikach. Jestem bardzo początkujący, dlatego jeśli ktoś mógłby mi wyjaśnić co robię źle i jak ten problem rozwiązać, to byłbym bardzo wdzięczny ;)