Układy równań w Delphi - działania na ujemnych współczynnikach

0

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 ;)

2

Zapoznaj się z pojęciem formatowania kodu: http://4programmers.net/Forum/998482

0

Pierwszy post poprawiony :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1