Inhaltsverzeichnis
3.2. Integration der vorhandenen Daten und Algorithmen
Zur Zerlegung in AGn wird der Algorithmus aus Abschnitt 2.2. mit der Erweiterung aus Abschnitt 2.3. zum Erkennen der Eigentlichkeit verwendet. Der MT wird dabei Schritt für Schritt um die jeweils letzte AG erleichtert. Zum Verwalten des jeweiligen Restmechanismus genügt dabei nicht die Gliedmatrix, denn für die Speicherung der Zuordnung zwischen Gliedern und AGn (Variable GliedAssurIndex) müssen die Gliednummern des Originalmechanismus verwendet werden, nicht die des Restmechanismus. Die Zuordnung der Original- zu den Restmechanismus-Gliednummern übernimmt ein Feld (Variable Original). Das Speichern der Gliedmatrix des Restmechanismus ist dann gar nicht mehr erforderlich, denn die vorhandenen Gelenke können mit Hilfe der Original-Gliednummern anhand der Original-Gliedmatrix erkannt werden.
Für die Darstellung von Teilmengen von Gliedern könnte der in PASCAL verfügbare Mengentyp verwendet werden. Allerdings gibt es diesen Typ in anderen verbreiteten Hochsprachen (z.B. C) nicht, was eine eventuell später gewünschte Portierung zusätzlich erschweren würde. Da es sich um Mengen von Gliedern handelt, ist die höchstmögliche Anzahl von Elementen 14. Die Mengen lassen sich daher in einer 32-bittigen Ganzzahl als Bitfeld speichern, womit das Problem der schlechten Portierbarkeit umgangen wird. Mengenoperationen mit einem solchen Bitfeld werden wie folgt implementiert:
Operation | Implementierung |
A∈M
|
M and (1 shl A) > 0
|
Zur endgültigen Implementierung der AGn-Zerlegung fehlt jetzt nur noch eine geeignete Methode, um die Teilstrukturen in der gewünschten Reihenfolge zu durchsuchen, also von der kleinsten zur größten. Mengen in der Reihenfolge aufsteigender Mächtigkeit zu generieren, ist sehr aufwändig. Deshalb wird eine andere Lösung gewählt: Die möglichen Teilmengen werden beim Laden der Bibliothek in der richtigen Reihenfolge in einem Feld (Variable AssurCheck) vorbereitet. Dadurch lässt sich auch die Forderung nach einer geraden Anzahl von Gliedern bei diesen Teilmengen relativ effizient erfüllen: es werden einfach nur die geradzahligen dort gespeichert.
Wie laufzeiteffizient der Algorithmus zum Vorbereiten der Teilmengen ausfällt, ist vergleichsweise unwichtig. Da er nur einmal pro Sitzung ausgeführt wird, spielen ein paar Millisekunden mehr oder weniger keine Rolle. Die Vorgehensweise, das Feld erst zu füllen und anschließend zu sortieren, wäre also völlig unproblematisch. Allerdings gibt es eine Methode, die nicht nur schneller, sondern in der Implementierung auch einfacher ist, da das anschließende Sortieren dabei einfach entfallen kann: Die Teilmengen werden bereits sortiert in das Feld geschrieben. Dazu wird das Feld vorher in Blöcke unterteilt, die jeweils nur Teilmengen der gleichen Größe aufnehmen. Dann werden alle Teilmengen untersucht und in den zugehörigen Block geschrieben. Damit sich am Ende eine fortlaufende Anordnung der Teilmengen im Feld ergibt, müssen die Blöcke exakt die richtige Größe haben. Diese lässt sich mittels Kombinatorik aber leicht im Voraus berechnen. Die genaue Implementierung ist im Quelltext (Seiten C 18 und C 19) zu sehen.
Insgesamt sind am Erkennen der zuletzt angefügten AG also folgende weiteren Variablen beteiligt:
var isel, {Index der gerade geprüften Teilmenge in AssurCheck} Selection, {gerade geprüfte Teilmenge (Bitfeld)} ngl0, {Anzahl der Glieder des aktuellen Restmechanismus} nge0, {Anzahl der Gelenke des aktuellen Restmechanismus} AssurSize, {Größe der gerade geprüften Teilmenge } det: integer; {doppelte Anzahl der Gelenke der gerade geprüfte Teilmenge} Original: nAr; {Original-Gliednummern der Glieder des aktuellen Restmechanismus} ab: kAr; {(ab[i]) ist Liste der Gelenke als Bitfeld} |
Der Algorithmus sieht damit so aus:
result:=false; AssurSize:=0; for isel:=0 to nAssurCheck[ngl0 div 2]-1 do begin {in AssurCheck vorbereitete Gliedergruppen durchsuchen} Selection:=AssurCheck[ngl0 div 2,isel]; if isel=AssurSizeStart[ngl0 div 2,AssurSize div 2+1] then inc(AssurSize,2); {ggf. AssurSize erhöhen} {Anzahl der Gelenke ermitteln:} det:=0; for i:=0 to nge0-1 do if ab[i] and Selection>0 then inc(det,2); if det=AssurSize*3 then begin result:=true; break {letzte Assur-Gruppe gefunden} end end; |
Ein komplettes Abarbeiten der Schleife ist bei einem korrekten MT nicht möglich, da immer mindestens eine zuletzt angefügte AG enthalten ist. Nach dem Durchlauf enthält die Variable Selection die zuletzt angefügte AG des Restmechanismus als Bitfeld. Ist der MT nicht korrekt und keine letzte AG enthalten, dann wurde die Schleife komplett abgearbeitet und die Variable result nicht auf true gesetzt.
Der Kern der AGn-Zerlegung ist damit fertig. Es fehlen noch folgende Operationen:
Die Implementierung dieser Operationen ist vergleichsweise einfach und im Quelltext (Seiten C 14 bis C 16) zu sehen. All diese Schritte werden solange wiederholt, bis der Restmechanismus nur noch aus zwei Gliedern besteht.
Anschließend muss noch die Eigentlichkeit des zerlegten MTs geprüft werden. Wie aus den markierten Gliedern eine Aussage über die Eigentlichkeit gewonnen werden kann, wurde in Abschnitt 2.3. dargelegt. Ggf. ist noch zu untersuchen, ob es sich um ein Übertragungsgetriebe handelt. Dazu müssen nur die Glieder der letzten AG anhand der Gliedmatrix auf Gelenke zum Gestell hin geprüft werden. Gibt es solche, dann ist der MT ein eigentliches Übertragungsgetriebe. Für die genaue Implementierung sei wieder auf den Quelltext (Seite C 16) verwiesen.
Sollen nun bei der AG-Zerlegung die Eigenschaften einer mit anderen MTen gemeinsamen kinematischen Kette ausgenutzt werden, dann bleibt dieser Algorithmus im Wesentlichen erhalten. Die einzige Änderung besteht darin, dass die erste erkannte AG mittels eines anderen Verfahrens gesucht wird: Statt aller Teilmengen (Variable AssurCheck) werden nur spezielle Teilmengen geprüft, die in dieser Kette potentielle AGn darstellen und in der Basiskette bei deren Analyse gefunden und gespeichert wurden (Feld AssurTestGlieder). Die Untersuchung der Gelenkzahl dieser Teilmengen kann entfallen, da es sich nach den Erkenntnissen aus Abschnitt 2.4. bei jeder von ihnen um eine Assur-Gruppe handelt - vorausgesetzt, weder Antrieb noch Gestell sind enthalten. Falls mehrere Teilmengen AGn sind, wird sinnvoller Weise die größte von ihnen gewählt, damit der Restmechanismus möglichst klein wird und dadurch schnell analysiert werden kann. Dazu müssen zwar alle AGn geprüft werden, statt die zuerst gefundene sofort verwenden zu können. Da es aber nur sehr wenige potentielle AGn pro Basiskette geben dürfte [Nachtrag: es sind maximal 19], spielt das in Bezug auf die Laufzeit im Vergleich zur Aussicht auf eine schnellere Reduktion des Restmechanismus keine Rolle.
Die Implementierung der AGn-Zerlegung unter Ausnutzung der Eigenschaften der kinematischen Kette könnte also so erfolgen, dass sie zuerst die erste AG nach ihrem eigenen Algorithmus sucht und anschießend den Restmechanismus an die allgemeine AGn-Zerlegung (Funktion AssurZerlegung) zur weiteren Untersuchung übergibt. Dazu müsste allerdings erst eine Gliedmatrix des Restmechanismus angelegt werden, da die allgemeine AGn-Zerlegung laut Entwurf des Interface keine anderen geeigneten Parameter besitzt; insbesondere nicht die intern zur Darstellung des Restmechanismus verwendete Zuordnung der Gliednummern zum Original-Mechanismus. Hier wird eine weniger aufwändige Lösung gewählt: Die eigentliche AGn-Zerlegung erfolgt in einer internen Funktion, die als zusätzlichen Parameter zu denen der Funktion AssurZerlegung die Angabe einer schon bekannten letzten AG zulässt:
procedure AssurZerlegung_Intern(Klasse: TStrukturKlasse; const M: TGliedmatrix; var MechInfo: TMechInfo; LetzteAssur, GroesseLetzteAssur: integer; AssurCodeBestimmung: boolean);
Die normale AGn-Zerlegung ruft diese Funktion einfach, ohne diesen zusätzlichen Parameter zu nutzen (LetzteAssur=0). Die AGn-Zerlegung unter Ausnutzen der Eigenschaften einer kinematischen Kette dagegen sucht zuerst die letzte AG nach ihrem schnelleren Verfahren und übergibt das Ergebnis dieser Suche dann ohne weitere Verarbeitung an die interne Funktion, die damit die erste Suche nach einer AG überspringen kann. Details der Implementierung sind im Quelltext der Typenbibliothek (Seiten C 17 und C 18) ersichtlich.