Berechnungsdeterminante einer Matrix (nxn) rekursiv

Ich bin dabei, einen Code zu schreiben, der die Determinante einer quadratischen Matrix (nxn) berechnet, mit dem Laplace-Algorithmus (Bedeutung des rekursiven Algorithmus) als geschriebene Laplace-Erweiterung der Wikipedia .

Ich habe bereits die Klasse Matrix , die init , setitem , getitem , repr und all die Dinge, die ich brauche, um die Determinante (einschließlich minor(i,j) ) zu berechnen.

Also habe ich den Code unten ausprobiert:

 def determinant(self,i=0) # i can be any of the matrix's rows assert isinstance(self,Matrix) n,m = self.dim() # Q.dim() returns the size of the matrix Q assert n == m if (n,m) == (1,1): return self[0,0] det = 0 for j in range(n): det += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).determinant()) return det 

Wie erwartet, in jedem rekursiven Ruf, wird sich self zu einem geeigneten Minderjährigen. Aber wenn ich von dem rekursiven Anruf zurückkomme, wechselt es nicht zu seiner ursprünglichen Matrix. Dies führt zu Schwierigkeiten, wenn in der for Schleife (wenn die Funktion an (n,m)==(1,1) ankommt, wird dieser ein Wert der Matrix zurückgegeben, aber in der for Schleife ist self noch eine 1×1-Matrix – warum ?)

4 Solutions collect form web for “Berechnungsdeterminante einer Matrix (nxn) rekursiv”

Hier ist die Funktion in Python 3.

Anmerkung: Ich verwendete eine eindimensionale Liste, um die Matrix zu beherbergen, und das Größenarray ist die Anzahl der Zeilen oder Spalten im quadratischen Array. Es verwendet einen rekursiven Algorithmus, um die Determinante zu finden.

 def solve(matrix,size): c = [] d = 0 print_matrix(matrix,size) if size == 0: for i in range(len(matrix)): d = d + matrix[i] return d elif len(matrix) == 4: c = (matrix[0] * matrix[3]) - (matrix[1] * matrix[2]) print(c) return c else: for j in range(size): new_matrix = [] for i in range(size*size): if i % size != j and i > = size: new_matrix.append(matrix[i]) c.append(solve(new_matrix,size-1) * matrix[j] * ((-1)**(j+2))) d = solve(c,0) return d 

Sind Sie sicher, dass Ihr minor das neue Objekt zurückgibt und nicht einen Verweis auf Ihr ursprüngliches Matrixobjekt? Ich habe Ihre genaue Determinantenmethode verwendet und eine minor Methode für Ihre Klasse implementiert, und es funktioniert gut für mich.

Unten ist eine schnelle / schmutzige Implementierung Ihrer Matrixklasse, da ich Ihre Implementierung nicht habe. Für die Kürze habe ich mich dafür entschieden, es nur für quadratische Matrizen zu implementieren, was in diesem Fall nicht wichtig sein sollte, wie es wir mit Determinanten zu tun haben. Achten Sie auf die Methode, das ist das gleiche wie Ihre, und minor Methode (der Rest der Methoden gibt es, um die Umsetzung und Prüfung zu erleichtern):

 class matrix: def __init__(self, n): self.data = [0.0 for i in range(n*n)] self.dim = n @classmethod def rand(self, n): import random a = matrix(n) for i in range(n): for j in range(n): a[i,j] = random.random() return a @classmethod def eye(self, n): a = matrix(n) for i in range(n): a[i,i] = 1.0 return a def __repr__(self): n = self.dim for i in range(n): print str(self.data[i*n: i*n+n]) return '' def __getitem__(self,(i,j)): assert i < self.dim and j < self.dim return self.data[self.dim*i + j] def __setitem__(self, (i, j), val): assert i < self.dim and j < self.dim self.data[self.dim*i + j] = float(val) # def minor(self, i,j): n = self.dim assert i < n and j < n a = matrix(self.dim-1) for k in range(n): for l in range(n): if k == i or l == j: continue if k < i: K = k else: K = k-1 if l < j: L = l else: L = l-1 a[K,L] = self[k,l] return a def det(self, i=0): n = self.dim if n == 1: return self[0,0] d = 0 for j in range(n): d += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).det()) return d def __mul__(self, v): n = self.dim a = matrix(n) for i in range(n): for j in range(n): a[i,j] = v * self[i,j] return a __rmul__ = __mul__ 

Jetzt zum Testen

 import numpy as np a = matrix(3) # same matrix from the Wikipedia page a[0,0] = 1 a[0,1] = 2 a[0,2] = 3 a[1,0] = 4 a[1,1] = 5 a[1,2] = 6 a[2,0] = 7 a[2,1] = 8 a[2,2] = 9 a.det() # returns 0.0 # trying with numpy the same matrix A = np.array(a.data).reshape([3,3]) print np.linalg.det(A) # returns -9.51619735393e-16 

Der Rest im Falle von numpy ist, weil es die Determinante durch (Gaußsche) Beseitigung Methode anstatt der Laplace Expansion berechnet. Sie können auch die Ergebnisse auf zufälligen Matrizen vergleichen, um zu sehen, dass der Unterschied zwischen Ihrer Determinantenfunktion und Numpy's nicht über die float Präzision hinaus wächst:

 import numpy as np a = 10*matrix.rand(4) A = np.array( a.data ).reshape([4,4]) print (np.linalg.det(A) - a.det())/a.det() # varies between zero and 1e-14 

Hey, ich habe einen Code in MATLAB mit rekursiver Funktion geschrieben. Dies könnte Ihnen behilflich sein.

 function value = determinant(A) % Calculates determinant of a square matrix A. % This is a recursive function. Not suitable for large matrices. [rows, columns] = size(A); if rows ~= columns error('input matrix is not a square matrix.') end value = 0; if rows == 2 for i = 1:rows value = A(1,1)*A(2,2) - A(1,2)*A(2,1); end else for i = 1:rows columnIndices = [1:i-1 i+1:rows]; value = value + (-1)^(i+1)*A(1,i)*... determinant(A(2:rows, columnIndices)); end end end 

Ich habe diesen Code gepostet, weil ich es nicht gut im Internet, wie man n * n Determinante mit nur Standard-Bibliothek zu lösen. Der Zweck ist, es mit denen zu teilen, die es nützlich finden werden. Ich begann mit der Berechnung der Submatrix Ai in Bezug auf eine (0, i). Und ich habe rekursive Determinante verwendet, um es kurz zu machen.

  def submatrix(M, c): B = [[1] * len(M) for i in range(len(M))] for l in range(len(M)): for k in range(len(M)): B[l][k] = M[l][k] B.pop(0) for i in range(len(B)): B[i].pop(c) return B def det(M): X = 0 if len(M) != len(M[0]): print('matrice non carrée') else: if len(M) <= 2: return M[0][0] * M[1][1] - M[0][1] * M[1][0] else: for i in range(len(M)): X = X + ((-1) ** (i)) * M[0][i] * det(submatrix(M, i)) return X 

Entschuldigung für nicht kommentieren vor Jungs 🙂 Wenn Sie eine weitere Erklärung brauchen, zögern Sie nicht zu fragen.

  • Python-Rekursions- und return-Anweisungen
  • Wie man sogar und ungerade Zahlen eines Arrays mit Rekursion summiert
  • Rekursive dircmp (vergleiche zwei Verzeichnisse, um sicherzustellen, dass sie die gleichen Dateien und Unterverzeichnisse haben)
  • Python-interpretator automatisch wiederherzustellen, ohne Antwort zurückzugeben
  • Finde alle Index mit Rekursion
  • Ist es möglich, die Rekursion aus dieser Funktion zu entfernen?
  • Baktracking-Funktion, die die Berechnung berechnet, überschreitet die maximale Rekursionstiefe
  • Rekursiv finden Sie die kth größte int in Liste der Liste der int in Python
  • Was ist die maximale Rekursionstiefe in Python und wie man es erhöht?
  • Rekursiv dekrementieren eine Liste durch 1
  • Rekursionsfunktion in Python
  • Python ist die beste Programmiersprache der Welt.