//Autor: Artur Czekalski (Sator) www.epokaY.net/artur artur@epokaY.net //Liczenie wyznacznika macierzy program Project1; {$APPTYPE CONSOLE} uses SysUtils, windows; //--------------------------------------------------------------------------- const gWymiar: Integer = 11; //liczba wierszy i kolumn w macierzy var Mat: array[0..11*11-1] of double; //macierz //--------------------------------------------------------------------------- Function PermLexSuccSelf(N: Integer; var P: array of Integer): bool; var i, j, w, k: Integer; begin //Ustala następnika permutacji w kolejności leksykogrficznej tzn. t[i]= 0) and (P[i+1] < P[i]) do Dec(i); //znajdź pierwszy od prawej, który psuje porządek rosnący If i = -1 Then begin RESULT := false; exit; end; //ostatnia permutacja while (j>i) and (P[j] <= P[i]) Do Dec(j); //znajdź element pierwszy od prawej > P[i] If j = i Then begin RESULT := false; exit; end; //to nie jest permutacja w := P[i]; P[i] := P[j]; P[j] := w; //zamień P[i] z P[j] k := i + (N-i-1) div 2; For j:=i+1 To k Do //zapisz w odwrotnej kolejności: od i+1 do n begin w := P[j]; P[j] := P[N+i-j]; P[N+i-j] := w; end; RESULT := true; //Jest następnik end; //--------------------------------------------------------------------------- Function LInwersji(N: Integer; var P: array of Integer): Integer; var i, j, LInw: Integer; begin //Podaje liczbę inwersji w permutacji P; np. 3,1,4,2 ma 3 inw.: (3,1),(3,2),(4,2) LInw := 0; For i:=0 To N-2 Do For j:=i+1 To N-1 Do if P[i] > P[j] Then Inc(LInw); RESULT := LInw; end; //-------------------------------------------------------------- Function DetMacierz(Wymiar: Integer; var M: array of double): double; var Suma, Iloczyn: double; i: Integer; P: array of Integer; //permutacja begin //Liczy wyznacznik macierzy M ze wzoru if Wymiar <= 1 Then begin RESULT := 0.0; exit; end; Suma := 0.0; SetLength(P, Wymiar); //przydzielenie pamięci For i:=0 To Wymiar-1 Do P[i] := i; //pierwsza permutacja //--------------------------- repeat begin Iloczyn := M[P[0]]; For i:=1 To Wymiar-1 Do Iloczyn := Iloczyn * M[ Wymiar*i + P[i] ]; If (LInwersji(Wymiar, P) mod 2) = 0 Then //parzysta liczba inwersji Suma := Suma + Iloczyn else Suma := Suma - Iloczyn; end until not PermLexSuccSelf(Wymiar, P); P := NIL; //jawne usunięcie tablicy RESULT := Suma; end; //=========================================================================== VAR czas: Cardinal; i: Integer; w: double; BEGIN //---Spr.1 Mat[0]:=1; Mat[1]:=2; Mat[2]:=3; Mat[3]:=4; writeln('Spr. Det st. 2 = ', DetMacierz(2, Mat):0:6); //---Spr.2 Mat[ 0]:=2; Mat[ 1]:= 9; Mat[ 2]:= 9; Mat[ 3]:= 4; Mat[ 4]:=2; Mat[ 5]:=-3; Mat[ 6]:=12; Mat[ 7]:= 8; Mat[ 8]:=4; Mat[ 9]:= 8; Mat[10]:= 3; Mat[11]:=-5; Mat[12]:=1; Mat[13]:= 2; Mat[14]:= 6; Mat[15]:= 4; writeln('Spr. Det st. 4 = ', DetMacierz(4, Mat):0:6); //--- For i:=0 To gWymiar*gWymiar-1 Do Mat[i] := i+1 - (i mod 3) - (i mod 5) + (i mod 10); For i:=0 To gWymiar*gWymiar-1 Do begin write(Mat[i]:4:0); If (i mod gWymiar) = gWymiar-1 Then writeln; end; w := 0.0; For i:=0 To gWymiar*gWymiar-1 Do w := w + Mat[i]; writeln('Suma wyrazow = ', w:0:6); //---Test czas := GetTickCount; w := DetMacierz(gWymiar, Mat); czas := GetTickCount - czas; writeln('Wyznacznik st. ', gWymiar, ' = ', w:0:6); write('Delphi 7.0 PE: Czas=', czas); readln; END.