Das Arbeiten mit numerischen Matrizen im Allgemeinen und das Lösen von Systemen linearer algebraischer Gleichungen im Besonderen ist ein klassisches mathematisches und algorithmisches Problem, das hĂ€ufig bei der Modellierung und Berechnung einer groĂen Klasse von GeschĂ€ftsprozessen (z. B. bei der Berechnung von Kosten) verwendet wird. Beim Erstellen und Betreiben von 1C: Enterprise-Konfigurationen standen viele Entwickler vor der Notwendigkeit, SLAU-Berechnungsalgorithmen manuell zu implementieren, und dann vor dem Problem, lange auf eine Lösung zu warten.
â1C: Enterpriseâ 8.3.14 enthĂ€lt Funktionen, mit denen sich die Zeit zum Lösen linearer Gleichungssysteme mithilfe eines auf der Graphentheorie basierenden Algorithmus erheblich verkĂŒrzen lĂ€sst.
Es ist fĂŒr die Verwendung mit Daten optimiert, die eine spĂ€rliche Struktur aufweisen (dh nicht mehr als 10% Koeffizienten ungleich Null in den Gleichungen enthalten), und zeigt im Durchschnitt und im besten Fall die Asymptotik Î (nâ
log (n) â
log (n)), wobei n ist Die Anzahl der Variablen und im schlimmsten Fall (wenn das System zu ~ 100% voll ist) ist sein asymptotisches Verhalten mit klassischen Algorithmen vergleichbar (Î (n
3 )). DarĂŒber hinaus zeigt der Algorithmus auf Systemen mit ~ 10
5 Unbekannten eine hundertfache Beschleunigung im Vergleich zu solchen, die in speziellen Bibliotheken fĂŒr lineare Algebra (z. B.
Superlu oder
Lapack )
implementiert sind .
Wichtig: Der Artikel und der beschriebene Algorithmus erfordern ein VerstÀndnis der linearen Algebra und der Graphentheorie im ersten Studienjahr einer UniversitÀt.Darstellung der SLAE als Grafik
Betrachten Sie das einfachste spÀrliche System linearer Gleichungen:
Achtung: Das System wird zufÀllig generiert und spÀter zur Demonstration der Schritte des Algorithmus verwendetAuf den ersten Blick entsteht eine Assoziation mit einem anderen mathematischen Objekt - der Graph-Adjazenz-Matrix. Warum also nicht die Daten in Adjazenzlisten konvertieren, RAM zur Laufzeit sparen und den Zugriff auf Koeffizienten ungleich Null beschleunigen?
Dazu reicht es aus, die Matrix zu transponieren und die Invariante
âA [i] [j] = z establish die i-te Variable gibt die j-te Gleichung mit dem Koeffizienten z einâ zu erstellen und dann fĂŒr jede Nicht-Null A [i] [j] die entsprechende Kante zu konstruieren vom Scheitelpunkt i zum Scheitelpunkt j.
Das resultierende Diagramm sieht folgendermaĂen aus:

Selbst visuell stellt sich heraus, dass es weniger umstÀndlich ist und die asymptotischen Speicherkosten von O (n
2 ) auf O (n + m) sinken, wobei m die Anzahl der Koeffizienten im System ist.
Isolierung schwach verbundener Komponenten
Die zweite algorithmische Idee, die bei der Betrachtung der resultierenden EntitĂ€t in den Sinn kommt: die Verwendung des Prinzips âTeilen und Erobernâ. In Bezug auf den Graphen fĂŒhrt dies zur Trennung des Satzes von Eckpunkten in schwach verbundene Komponenten.
Ich möchte Sie daran erinnern, dass die schwach verbundene Komponente eine solche Teilmenge von Scheitelpunkten ist, die maximal eingeschlossen ist, dass zwischen zwei beliebigen Punkten ein Pfad von Kanten in einem ungerichteten Diagramm existiert. Wir können einen ungerichteten Graphen aus dem ursprĂŒnglichen erhalten, indem wir beispielsweise jeder Kante das Gegenteil hinzufĂŒgen (mit anschlieĂender Entfernung). Dann enthĂ€lt ein Scheitelpunkt der Verbindung alle Scheitelpunkte, die wir erreichen können, wenn wir den Graphen in der Tiefe umrunden.
Nach der Trennung der schwach verbundenen Komponenten hat der Graph die folgende Form:

Im Rahmen der Analyse eines linearen Gleichungssystems bedeutet dies, dass kein einziger Scheitelpunkt aus der ersten Komponente in den Gleichungen mit den Zahlen der zweiten Komponente enthalten ist und umgekehrt, dh wir können diese Subsysteme unabhÀngig voneinander lösen (z. B. parallel).
Scheitelpunktreduzierung
Der nĂ€chste Schritt des Algorithmus ist genau die Optimierung fĂŒr die Arbeit mit spĂ€rlichen Matrizen. Selbst in der Grafik aus dem Beispiel gibt es "hĂ€ngende" Peaks, was bedeutet, dass einige der Gleichungen nur einen Unbekannten enthalten und der Wert dieses Unbekannten bekanntlich leicht zu finden ist.
Um solche Gleichungen zu bestimmen, wird vorgeschlagen, ein Array von Listen zu speichern, die die Anzahl der in der Gleichung enthaltenen Variablen mit der Nummer dieses Array-Elements enthalten. Wenn die Liste die EinheitsgröĂe erreicht, können wir den âeinzigenâ Scheitelpunkt reduzieren und den Rest der Gleichungen in den anderen Gleichungen, in die dieser Scheitelpunkt eingeht, informieren.
Somit können wir den Scheitelpunkt 3 unmittelbar nach der vollstÀndigen Verarbeitung der Komponente aus dem Beispiel reduzieren:
8â
3=4â3=1/2
Ăhnlich verfahren wir mit Gleichung 0, da sie nur eine Variable enthĂ€lt:
1â
x1=1âx1=1
Andere Gleichungen Àndern sich ebenfalls, nachdem dieses Ergebnis gefunden wurde:
$$ display $$ 1â
_1 ââ+ 1â
_2 = 3â1â
_2 = 3-1 = 2 $$ display $$
Das Diagramm hat die folgende Form:

Beachten Sie, dass beim Reduzieren eines Scheitelpunkts möglicherweise auch andere angezeigt werden, die ebenfalls einen unbekannten enthalten. Daher sollte dieser Schritt des Algorithmus wiederholt werden, bis mindestens einer der Eckpunkte reduziert werden kann.
Graph neu erstellen
Die aufmerksamsten Leser könnten feststellen, dass eine Situation möglich ist, in der jeder der Scheitelpunkte des Diagramms einen Grad von mindestens zwei aufweist und es unmöglich ist, die Scheitelpunkte weiterhin konsequent zu reduzieren.
Das einfachste Beispiel fĂŒr einen solchen Graphen: Jeder Scheitelpunkt hat einen Auftrittsgrad von zwei, keiner der Scheitelpunkte kann reduziert werden.
Im Rahmen der Optimierung fĂŒr dĂŒnn besetzte Matrizen wird davon ausgegangen, dass solche Untergraphen klein sind. Sie mĂŒssen jedoch noch mit ihnen arbeiten. Um die Werte der Unbekannten zu berechnen, die Teil des Gleichungssystems sind, wird vorgeschlagen, klassische Methoden zur Lösung von SLAEs zu verwenden (aus diesem Grund zeigt die EinfĂŒhrung, dass unser Algorithmus fĂŒr eine Matrix, in der alle oder fast alle Koeffizienten in den Gleichungen ungleich Null sind, dieselbe asymptotische KomplexitĂ€t aufweist wie die Standardkoeffizienten )
Sie können beispielsweise die nach der Reduktion verbleibenden Scheitelpunkte wieder in die Matrixform bringen und
die GauĂ-Methode zum Lösen von SLAEs darauf anwenden . Auf diese Weise erhalten wir die genaue Lösung, und die Geschwindigkeit des Algorithmus wird verringert, da nicht das gesamte System, sondern nur ein Teil davon verarbeitet wird.
Algorithmus testen
Um die Software-Implementierung des Algorithmus zu testen, haben wir mehrere reale Gleichungssysteme mit groĂem Volumen sowie eine groĂe Anzahl zufĂ€llig generierter Systeme verwendet.
Die Erzeugung eines zufĂ€lligen Gleichungssystems erfolgte durch sequentielles HinzufĂŒgen von Kanten beliebigen Gewichts zwischen zwei zufĂ€lligen Eckpunkten. Insgesamt war das System zu 5-10% voll. Die Richtigkeit der Lösungen wurde ĂŒberprĂŒft, indem die erhaltenen Antworten in das ursprĂŒngliche Gleichungssystem eingesetzt wurden.
Die Systeme reichten von 1.000 bis 200.000 UnbekanntenUm die Leistung zu vergleichen, haben wir die beliebtesten Bibliotheken zur Lösung linearer Algebra-Probleme wie Superlu und Lapack verwendet. NatĂŒrlich konzentrieren sich diese Bibliotheken auf die Lösung einer Vielzahl von Problemen, und die Lösung von SLAE in ihnen ist in keiner Weise optimiert, sodass sich der Geschwindigkeitsunterschied als signifikant herausstellte.
Testen der Lapack-Bibliothek
Testen der Bibliothek 'superlu'Hier ist der endgĂŒltige Vergleich unseres Algorithmus mit den in gĂ€ngigen Bibliotheken implementierten Algorithmen:

Fazit
Auch wenn Sie kein Entwickler von 1C: Enterprise-Konfigurationen sind, können Sie die in diesem Artikel beschriebenen Ideen und Optimierungsmethoden nicht nur bei der Implementierung eines Algorithmus zur Lösung von SLAEs verwenden, sondern auch fĂŒr eine ganze Klasse von linearen Algebra-Problemen, die mit Matrizen verbunden sind.
FĂŒr 1C-Entwickler fĂŒgen wir hinzu, dass die neue FunktionalitĂ€t der SLAE-Lösung die parallele Verwendung von Computerressourcen unterstĂŒtzt und Sie die Anzahl der verwendeten Berechnungsthreads anpassen können.