Bauinformatik Teil 1 Übungsskript 2011 Universität Duisburg-Essen Fakultät für Ingenieurwissenschaften Abteilung Bauwissenschaften Institut für Baustatik Dr. E. Baeck 19.10.2011 INHALTSVERZEICHNIS Seite iii Inhaltsverzeichnis 1 Arbeiten mit EXCEL 1.1 Bezüge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Fehlermeldungen . . . . . . . . . . . . . . . . . . . . . . . . 1.3 EXCEL-Funktionen . . . . . . . . . . . . . . . . . . . . . . 1.3.1 SUMME . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 ABS . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3 MAX, MIN . . . . . . . . . . . . . . . . . . . . . . . 1.3.4 WENN . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.5 SVERWEIS . . . . . . . . . . . . . . . . . . . . . . . 1.4 Aufgabe 1: Summe, Extremwerte und Absolutbetrag . . . 1.5 Aufgabe 2: Nachweis eines statisch unbestimmten Trägers . . . . . . . . . . 2 2 2 3 3 3 3 3 4 4 5 2 Zahlensysteme 2.1 Motivation und Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Beispiele zur Konvertierung zwischen Zahlensystemen . . . . . . . . . . . . . . . 2.3 Darstellung negativer Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 10 3 Die VBA-IDE 3.1 Oberfläche und Projektbrowser . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Testen eines Programms, Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . 11 11 12 4 VBA-Interface 4.1 Beispiel 1 in 6 Schritten . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Schritt 1: Gestaltung der Oberfläche . . . . . . . . . . . 4.1.2 Schritt 2: Gestaltung der Steuerelemente . . . . . . . . . 4.1.3 Schritt 3: Generieren eines Moduls für Funktion Summe 4.1.4 Schritt 4: Das Programm Summe . . . . . . . . . . . . . 4.1.5 Schritt 5: Programmtests . . . . . . . . . . . . . . . . . 4.1.6 Schritt 6: Das Ziel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 14 14 15 16 16 17 18 . . . . . . . . . . . 19 19 19 20 20 20 21 21 22 22 22 23 5 Elementare Algorithmen 5.1 Fakultät . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Binomialkoeffizient . . . . . . . . . . . . . . . . . . 5.3 Winkel zwischen 2 Vektoren des Rn . . . . . . . . 5.3.1 Pseudocode für Hauptprogramm . . . . . . 5.3.2 Pseudocode für Funktion SP rod . . . . . . 5.4 Reihenentwicklungen . . . . . . . . . . . . . . . . . 5.4.1 Entwicklung der Funktion sinus . . . . . . 5.4.2 Reihenentwicklung weiterer Funktionen . . 5.5 Newton-Verfahren . . . . . . . . . . . . . . . . . . 5.5.1 Der Algorithmus des 1-dimensionalen Falls 5.5.2 Pseudo-Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19.10.2011 Seite iv Bauinformatik - Teil 1 - Übungsskript / 2011 5.5.3 Programmablaufplan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 5.5.4 Nassi-Schneidermann-Diagramm . . . . . . . . . . . . . . . . . . . . . . . 24 5.5.5 Die Oberfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.5.6 Animation des Verfahrens . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 6 Elementare Sortiert-Algorithmen 26 6.1 Select-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 6.2 Bubble-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 7 Arbeiten mit Dateien 28 7.1 Dateioperationen für sequentiellen Zugriff . . . . . . . . . . . . . . . . . . . . . . 28 7.2 Torsionsträgeheitsmoments nach 2. Brendt’scher Formel . . . . . . . . . . . . . . 29 8 Das Clapeyron-Problem 30 8.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 8.2 Oberflächenlayout und Eingabe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 8.2.1 Feldbeschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8.2.2 Lastbeschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 ER-Modell der Datenstruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.3.1 ER-Modell der Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 8.3.2 ER-Modell der Belastung . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Aufbau der Datenstruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 8.4.1 Die Datenstruktur des Systems . . . . . . . . . . . . . . . . . . . . . . . . 34 8.4.2 Die Datenstruktur der Belastungen . . . . . . . . . . . . . . . . . . . . . . 35 Aufbau des Linearen Gleichungssystems . . . . . . . . . . . . . . . . . . . . . . . 37 8.5.1 Aufbau der Koeffizientenmatrix . . . . . . . . . . . . . . . . . . . . . . . . 37 8.5.2 Aufbau der Lastvektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 8.3 8.4 8.5 9 VBA-Objekte 40 9.1 Konstruktor und Destruktor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 9.2 Vektoren und Matrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 9.2.1 Methoden des Klassenmoduls Vektor . . . . . . . . . . . . . . . . . . . . . 41 9.2.2 Methoden des Klassenmoduls Matrix . . . . . . . . . . . . . . . . . . . . . 41 9.3 Die Containerklasse Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 9.4 Datenstruktur eines Stabwerks . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 9.4.1 Die Oberfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 9.4.2 Methoden des Punktes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 9.4.3 Methoden des Stabes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 2-fach verkettete lineare Listen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 9.5.1 Beispiel einer 2-fach verketten Liste . . . . . . . . . . . . . . . . . . . . . 47 9.5.2 Einfügen eines Datenknotens . . . . . . . . . . . . . . . . . . . . . . . . . 47 9.5.3 Entfernen eines Datenknotens . . . . . . . . . . . . . . . . . . . . . . . . . 47 9.5.4 Iteratoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 9.5 10 Rekursive Algorithmen 10.1 Quick-Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E. Baeck 49 49 INHALTSVERZEICHNIS Seite v A Dreimomentengleichung, Clapeyron 51 A.1 Das Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 A.2 Herleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 B Das ER-Modell 54 C UML-Aspekte 55 D Gauß’scher Algorithmus und Cholesky-Zerlegung 56 D.1 Der Gauß’sche Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 D.2 Interpretation des Gauß’schen Algorithmuses als Dreieckszerlegung . . . . . . . . 58 D.3 Die Cholesky-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 D.4 Pseudocode für Cholesky-Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . 62 D.4.1 Pseudocode der Zerlegung . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 D.4.2 Pseudocode des Vorwärtseinsetzens . . . . . . . . . . . . . . . . . . . . . . 62 D.4.3 Pseudocode des Rückwärtseinsetzens . . . . . . . . . . . . . . . . . . . . . 62 D.5 VBA-Code des Gleichungslösers nach Cholesky . . . . . . . . . . . . . . . . . . . 63 D.5.1 VBA-Code der Cholesky-Zerlegung . . . . . . . . . . . . . . . . . . . . . . 63 D.5.2 VBA-Code des Vorwärtseinsetzens . . . . . . . . . . . . . . . . . . . . . . 64 D.5.3 VBA-Code des Rückwärtseinsetzens . . . . . . . . . . . . . . . . . . . . . 64 E Lösungen zum Abschnitt Elementare Algorithmen 65 E.1 Summe aller Zahlen aus vorgegebenem Intervall . . . . . . . . . . . . . . . . . . . 65 E.2 Berechnung der Fakultät . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 E.3 Berechnung des Binomialkoeffizienten . . . . . . . . . . . . . . . . . . . . . . . . 67 E.4 Beispiel 4: Winkel zwischen 2 Vektoren im Rn . . . . . . . . . . . . . . . . . . . . 68 E.5 Lösung der sinus-Entwicklung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 E.6 Implementierung des Newton-Verfahrens . . . . . . . . . . . . . . . . . . . . . . . 72 F Lösungen zum Clapeyron-Problem 74 F.1 Aufgabe 8.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 F.2 Aufgabe 8.3.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 F.3 Einlesen der Systemdaten und Aufbau des Datenmodell . . . . . . . . . . . . . . 76 F.4 Einlesen der Belastungsdaten und Aufbau des Datenmodell . . . . . . . . . . . . 77 F.4.1 Aufbau des Lastfall-Indexvektors . . . . . . . . . . . . . . . . . . . . . . . 77 F.4.2 Aufbau des Lastfall-Containers . . . . . . . . . . . . . . . . . . . . . . . . 79 F.4.3 Aufbau der Koeffizientenmatrix . . . . . . . . . . . . . . . . . . . . . . . . 81 F.4.4 Lesen einer kompakt gespeicherten Bandmatrix . . . . . . . . . . . . . . . 82 F.4.5 Das Hauptprogramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 G Lösungen zum Abschnitt Vektor- und Matrixobjekte 84 G.1 Deklaration eines Vektor-Klassenmoduls . . . . . . . . . . . . . . . . . . . . . . . 84 G.2 Deklaration eines Matrix-Klassenmoduls . . . . . . . . . . . . . . . . . . . . . . . 86 G.3 Programm Vektor 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 G.4 Programm Vektor Drehen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 H Lösungen zum Abschnitt Rahmen und Collection 90 19.10.2011 INHALTSVERZEICHNIS Seite 1 H.1 Deklaration des Stab-Klassenmoduls . . . . . H.2 Deklaration des Knoten-Klassenmoduls . . . H.3 Implementierung des Anwendungsprogramms H.3.1 Die Listen . . . . . . . . . . . . . . . . H.3.2 Die Funktion Einlesen . . . . . . . . . H.3.3 Die Funktion Ausgabe . . . . . . . . . H.3.4 Die Funktion Verschieben . . . . . . . H.3.5 Die Funktion StabAnzahl . . . . . . . H.3.6 Die Ereignisfunktionen . . . . . . . . . I . . . . . . . . . . . . . . . . . . . . . . . . . . . Lösungen zum Abschnitt 2-fach verkettete Listen I.1 Deklaration des VNode-Klassenmoduls . . . . . . . I.2 Deklaration des VListe-Klassenmoduls . . . . . . . I.2.1 Daten am Listenkopf einfügen . . . . . . . . I.2.2 Daten am Listenende einfügen . . . . . . . I.2.3 Vorwärtsiterator . . . . . . . . . . . . . . . I.2.4 Einfügen eines Knotens . . . . . . . . . . . J Lösungen zu Sortieralgorithmen J.1 Die Ereignisfunktionen . . . . . . . . . . J.2 Generierung der Zufallszahlen . . . . . . J.3 Sortieralgorithmen . . . . . . . . . . . . J.3.1 Implementierung von SelectSort J.3.2 Implementierung von BubbleSort J.3.3 Implementierung von QuickSort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . K Lösung zur Brendt’schen Formel K.1 Die Ereignisfunktion zur Festlegung des Dateinamens . K.2 Die Ereignisfunktion zu Datenimport und Berechnung K.3 Die Datenstruktur . . . . . . . . . . . . . . . . . . . . K.4 Einlesen der Daten aus der Profil-Textdatei . . . . . . K.5 Hilfsfunktionen der Berechnung . . . . . . . . . . . . . K.5.1 Berechnung der mittlerern Blechdicke . . . . . K.5.2 Berechnung des Knotenabstandes . . . . . . . . K.5.3 Berechnung der Polygonfläche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 90 91 91 91 93 94 94 94 . . . . . . 96 96 96 97 97 98 99 . . . . . . 100 101 101 103 103 104 105 . . . . . . . . 107 107 107 108 108 110 110 110 111 19.10.2011 Seite 2 1 Bauinformatik - Teil 1 - Übungsskript / 2011 Arbeiten mit EXCEL 1.1 Bezüge Die Adressierung der EXCEL-Tabellenfelder (Bezüge) erfolgt über relative und absolute Bezüge bzw. über Namen (Bezeichnung eines Bezuges). • Indizierung B3 Z3S2 Standardindizierung von Spalte und Zeile B:⇒ Spalte 2 3:⇒ Zeile 3 Z1S1 -Indizierung von Spalte und Zeile S2:⇒ Spalte 2 Z3:⇒ Zeile 3 • Relative Bezüge Beim Kopieren wird auf relative Bezüge die Verschiebung aufaddiert. Verschiebung 4 Spalten und 3 Zeilen: B3 Z3S2 ⇒ F6 ⇒ Z(-3)S(-4) • Absolute Bezüge $B3 $B$3 Beim Kopieren wird der Spaltenbezug erhalten. Beim Kopieren wird der Spalten- und Zeilenbezug erhalten. • Namen Ein Name ist gleichbedeutende mit einem absoluten Bezug auf ein oder mehrere Tabellenfelder. 1.2 Fehlermeldungen Fehler Beispiel ### Beschreibung Die Zelle ist für die vorgegebene Ausgabe zu schmal. #WERT! =Abs(A3:A5) Unzulässiger Funktionswert. #DIV! =A2/A3, bei A3=0 Nulldivision. #NAME? =NoName Bezeichnung eines Bezugs oder einer Funktion ist unbekannt. #ZAHL! =Exp(1000) Zahlendarstellung nicht möglich. Überlauf. #NV! =SVerweis(...) Gesuchter Wert nicht verfügbar. Verweisfehler. #BEZUG! =Z(-3)S(-4) E. Baeck Der Bezug liegt außerhalb des zulässigen Bereichs, d.h. außerhalb der Tabelle. 1. ARBEITEN MIT EXCEL 1.3 Seite 3 EXCEL-Funktionen Nachfolgend werden die EXCEL-Funktionen zusammengestellt, die zur Bearbeitung der Übungsbeispiele herangezogen werden sollten. 1.3.1 SUMME Summe berechnet die Summe der Zellenwerte eines Bezugs. Beispiel: =Summe(A3:G3) 1.3.2 ABS ABS berechnet den Absolutbetrag eines Zellenwerts. Beispiel: =Abs(A3) 1.3.3 MAX, MIN MAX bzw. MIN ermittelt den maximalen bzw. minimalen Wert innerhalb eines Bezugs. Beispiel: 1.3.4 =Max(A3:G3) =Min(A3:G3) WENN Mit der Funktion WENN wird in Abhängigkeit eines boolschen Ausdrucks ein DANN -Wert oder ein SONST -Wert zugewiesen. Beispiel: =WENN(D13<1;"ja";"nein") Abbildung 1: WENN-Funktion Parameter Beschreibung AB Boolscher Ausdruck mit den Werte Wahr oder Falsch. WD Falls AB = W ahr, wird der Wert WD zugewiesen. WS Falls AB = F alsch, wird der Wert WS zugewiesen. 19.10.2011 Seite 4 1.3.5 Bauinformatik - Teil 1 - Übungsskript / 2011 SVERWEIS Mit der Matrix-Suchfunktion SVERWEIS lassen sich Daten aus Datenbanken, d.h. aus Bezügen in beliebigen Tabellen, unter Vorgabe eines Suchbegriffs extrahieren. Beispiel: =SVerweis(E3;A3:C5;2;FALSCH) Abbildung 2: SVERWEIS-Funktion Parameter Beschreibung ST Suchwert: Text, Zahl oder Wahrheitswert. MD Datenmatrix. Ein Bezug in einer beliebigen Tabelle. NS Spaltenindex der gewünschten Datenspalte. (Spalte 1 ist Suchspalte). Sortierkenner: Wahr ⇒ sortiert, Falsch ⇒ unsortiert. KS 1.4 Aufgabe 1: Summe, Extremwerte und Absolutbetrag In einem Bezug A1:D5 werden beliebige Zahlen eingetragen. Es sind die folgenden Größen zu ermitteln (siehe Abbildung 3): • Die Spalten- und Zeilensummen sowie die Gesamtsumme. • Maximaler und Minimaler Wert. • Maximaler Absolutwert. • Mit einer WENN-Funktion soll ausgegeben werden ob nur negative, nur positive oder negative und positive Werte gefunden wurden. Abbildung 3: Auswertung eines Bereichs E. Baeck 1. ARBEITEN MIT EXCEL 1.5 Seite 5 Aufgabe 2: Nachweis eines statisch unbestimmten Trägers Die Datenfelder sind in Formeln jeweils mit Namen anzusprechen1 Ein statisch unbestimmter Träger (siehe Abbildung 4) ist für vorgegebene Trägerlänge l und Steckenlast q für vorgegebenes Material (Stahltabelle) und Profil (Profiltabelle) nachzuweisen. Der E-Modul E der Stahlsorte sowie das Widerstandsmoment W sind aus einer Tabelle mittels der Suchfunktion SVERWEIS zu ermitteln (siehe Abbildung 5). Es ist zunächst zu berechnen, die Gesamtlast P , die beidseitigen Auflagerkräfte A = 3/8 ∗ P bzw. B = 5/8 ∗ P , das Einspannmoment MB = −1/8 ∗ P ∗ l und die Biegespannung am Lager B σ = MB /W . Die Eingabefelder der Tabelle sind als solche entsprechend zu kennzeichnen (siehe Abbildung 4). Achten Sie auch auf die Anpassung der unterschiedlichen Dimensionen. Abbildung 4: Nachweis eines statisch unbestimmten Trägers 1 Namen können im Untermenü Einfügen/Namen eingefügt und bearbeitet werden. 19.10.2011 Seite 6 Bauinformatik - Teil 1 - Übungsskript / 2011 Die Datenbanken für Material und Profile sollten in einer zweiten EXCEL-Tabelle der Mappe angelegt werden. Abbildung 5: Material- und Querschnittswerte in einer Datenbank 3 2 3 −3∗l∗x +2∗x ) in AbhängigIn einem weiteren Schritt ist die Durchbiegung des Trägers y = P ∗x∗(l 48∗E∗I∗l keit der Längskoordinate x zu ermitteln und mit dem Diagrammassistenten darzustellen. Als Diagrammtyp ist der Typ Punkt(XY) auszuwählen. Die Balkenlängsrichtung liegt in X-Richtung, die Durchbiegung in negative Y-Richtung (Faktor -1). E. Baeck 2. ZAHLENSYSTEME 2 Seite 7 Zahlensysteme Ein Zahlensystem wird zur Darstellung von Zahlen verwendet. Eine Zahl wird dabei nach den Regeln des jeweiligen Zahlensystems als Folge von Ziffern beziehungsweise Zahlzeichen dargestellt. In einem Stellenwertsystem (auch polyadisches Zahlensystem) bestimmt die Stelle (Position) den Wert der jeweiligen Ziffer. Die niederwertigste Position steht dabei im Allgemeinen rechts. Ein Stellenwertsystem hat eine Basis b (man spricht auch von einem b-adischen Zahlensystem). Jede Zifferposition hat einen Wert, der einer Potenz der Basis entspricht. Für die n-te Position hat man einen Wert von bn−1 (wenn die niederwertigste Position mit 1 nummeriert ist). Die Berechnung des Zahlenwertes erfolgt durch Multiplikation der einzelnen Ziffernwerte zi mit den zugehörigen Stellenwerten bi und der Addition dieser Produkte: Zahlenwert = zn · bn + . . . + zi · bi + . . . + z0 · b0 . 2.1 (1) Motivation und Anwendung Im Allgemeinen wird das Zahlensystem zur Basis 10 eingesetzt. Es gibt jedoch Anwendungsfälle, in denen das Zahlensystem zur Basis 10 ungeeignet ist. Aufgrund des digitalen Aufbaus eines Computers eignet sich das Zahlensystem zur Basis 10 zur Darstellung der Bit-Information in keinster Weise. Es verschleiert die Zusammenhänge, die mit Anwendung eines Zahlensystems zur Basis 2 oder zur Basis einer 2er Potenz einfach und klar in Erscheinung treten würden. Vergleichbar ist dieser Zusammenhang der Anwendung verschiedener Koordinatensysteme. So ist z.B. die Beschreibung einer rechteckigen Fläche im 2 dimensionalen karthesischen Koordinatensystem sehr einfach. Hierbei entkoppeln die Unterdimensionen Länge und Breite (siehe Abb. 6). Eine Fläche ist allein durch Vorgabe dieser Werte möglich. Soll demgegenüber eine Kreisfläche im 2 dimensionalen karthesischen Koordinatensystem beAbbildung 6: Rechteckfläche schrieben werden, so sind die Unterdimensionen Länge und Breite offensichtlich gekoppelt. Eine Vorgabe dieser Werte allein reicht nicht mehr aus, um die Fläche zu beschreiben (siehe Abb. 7). Wählt man hingegen ein polares Koordinatensystem mit den Unterdimensionen Radius und Winkel, so ist es wieder möglich durch Vorgabe zweier Werte, in diesem Fall Radius und Winkelbereich, eine Kreisfläche zu beschreiben. Da der Computer aufbauend auf der logischen Elementareinheit Bit (0 und 1 / aus und ein) in Paketen von zumeist 8 Bits (1 Byte) strukturiert ist, empfiehlt es sich aufgrund der Unübersichtlichkeit des dualen Zahlensystems Bits zur gruppieren. Werden 3 Bits gruppiert erhält man als natürliches Zahlensystem das Zahlensystem zur Basis 8 (Oktalsystem). Werden 4 Bits gruppiert erhält man als natürliches Zahlensystem das Zahlensystem zur Basis 16 (Hexadezimalsystem). 19.10.2011 Seite 8 Bauinformatik - Teil 1 - Übungsskript / 2011 Abbildung 7: Kreisfläche in karthesischen und polaren Koordinaten 2.2 Beispiele zur Konvertierung zwischen Zahlensystemen Beispiel 1: Konvertierung von 1425 in das Zahlensystem zur Basis b = 3. • Schritt 1: Konvertierung in das 10-System 1425 = 1 · 52 + 4 · 51 + 2 · 50 = 2510 + 2010 + 210 = 4710 • Schritt 2a: Konvertierung in das 3-System vollständig über 10-System 4710 = 1 · 33 + 2 · 32 + 0 · 31 + 2 · 30 = 4510 + 010 + 210 = 12023 • Schritt 2b: Ziffernweise Konvertierung in das 3-System 1425 = 1 · 52 + 4 · 51 + 2 · 50 = 2510 + 2010 + 210 = 2213 + 2023 + 23 = 12023 E. Baeck 2. ZAHLENSYSTEME Seite 9 Beispiel 2: Konvertierung von 14210 in das Zahlensystem zur Basis b = 6. Der Algorithmus zur Konvertierung einer Zahl in das Zahlensystem zur Basis b erfolgt durch b-Division und aufsammeln der Divisionsreste nach dem folgenden Prinzip (siehe Abb. 8). 142 wird durch 6 dividiert. Dies ergibt 23 Rest 4 23 wird durch 6 dividiert. Dies ergibt 3 Rest 5 3 wird durch 6 dividiert. Dies ergibt 0 Rest 3 Abbildung 8: Rechteckfläche Die erhaltenen Reste 4, 5 und 3 werden in die Reihenfolge von unten nach oben gebracht und von links nach rechts hin geschrieben. Damit erhalten wir die Zahl 3546 . In Abbildung 8 wird die Umrechnung in einer EXCEL-Tabelle implementiert (siehe dazu auch Abschnitt 1). In A2 wird die zu konvertierende Zahl eingetragen. Der Divisor ist stets b, also 6. Das Ergebnis der ganzzahligen Division erhalten wir mit der Formel =GANZZAHL(A2/B2). Der Divisionsrest in der grünen Spalte ergibt sich mit der Formel =REST(A2;B2). Das Ergebnis der ganzzahligen Division orange Felder werden in der folgenden Zeile in die Spalte des Dividenden eingetragen. Die Formel der ersten Zeile kann in die zweite Zeile eingetragen kopiert werden. Die Bezüge werden dabei, da relative Adressen verwendet werden, automatisch angepasst. In der Spalte E werden zur Kontrolle alle Anteile der Ziffern berechnet und in E6 zum Kontrollwert aufaddiert. Ein Übungsbeispiel: In nachfolgendem Übungsbeispiel ist in der Tabelle die in Spalte Zahl gegebene Zahl in die verschiedenen Zahlensysteme zur Basis b umzurechnen. Zahl b = 2 b=5 b=7 b=8 b = 10 b = 16 20213 4536 2467 2468 3310 2F16 Tabelle 1: Zahlensysteme 19.10.2011 Seite 10 2.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Darstellung negativer Zahlen Negative Zahlen können bei einer endlichen Ziffernbreite so konstruiert werden, dass die Summe aus positiver und negative Zahl gerade die Zahl ergibt, die im Bereich der Ziffernbreite alle Ziffern zu Null setzt und einen Übertrag von 1 erzeugt, der aufgrund der beschränkten Ziffernbreite und eines Überlaufs nicht mehr darstellbar ist. So verbleiben also die ausgenullten Ziffern und die führende 1 verschwindet. Im Rahmen der vorliegenden Ziffernbreite ist das aber gerade die Darstellung des Null-Wertes. Die Konstruktion der negativen Zahl beginnt mit dem sogenannten Stellenkomplement. Das Stellenkomplement ist die Zahl, deren Ziffern sich ergeben zu b − z − 1, d.h. wir subtrahieren von der Basis b die gegebenen Ziffer und die 1. Eine Summe aus Stellenkomplement und gegebener Zahl ergibt demnach eine Ziffernfolge, die nur die größte Ziffer, also b − 1 enthält. Wenn wir auf diese Ziffernfolge eins aufaddieren wird ein Übertrag erzeugt, der aufgrund der Begrenzung der Ziffernbreite verschwindet und alle Ziffern werden auf Null gesetzt. Damit ist die Darstellung der negativen Zahl, das b-Komplement, gegeben durch das um eins inkrementierte Stellenkomplement. In der Tabelle 2 sind die Darstellungen der negativen Zahlen im angegebenen b-Komplement (Zahlensystemkomplement) bei vorgegebener Ziffernbreite einzutragen. Beispiel: b-Komplement der Zahl 3467 bei einer Ziffernbreite von 4. Anmerkungen 03467 zu komplementierende Zahl mit 4 Ziffer 63207 Stellenkomplement: Komplementziffer = 6 -Ziffer + 1 b-Komplement = Stellenkomplement +1 63217 b-Komplement der Zahl Addition von Zahl und b-Komplement 03467 zu komplementierende Zahl + 63217 b-Komplement 100007 Wird der Überlauf abgeschnitten ist das Ergebnis der Addition Null. Zahl Breite b − Komplement −20213 6 −4536 6 −2467 5 −2468 5 −3310 4 −2F16 4 Tabelle 2: b-Komplement E. Baeck 3. DIE VBA-IDE 3 Seite 11 Die VBA-IDE Die VBA-IDE, (integrierte Entwicklungsumgebung) ist in allen Applikationen verfügbar, die VBA zur Automation einsetzten (z.B. MS-Office-Programm, AutoCAD, RStab, etc.). 3.1 Oberfläche und Projektbrowser Die VBA-IDE wird standardmäßig über Alt-F11 oder Extras/Makro/Visual-BasicEditor gestartet. Sie besteht aus einem Editor, einem Code-Generator für Rahmenprogramme ausgewählter Eventfunktionen und einem Programmtestmodul (Debugger) (siehe Abbildung 9). Abbildung 9: VBA-IDE Im Projektbrowser werden die folgenden Ordner angezeigt. • MS-EXCEL-Objekte Der Ordner enthält alle Tabellen der EXCEL-Datei (Workbook). • Modul -Objekte Der Ordner enthält Modul-Objekte, die ihrerseits die Quellen sequentieller (konventioneller) Programme enthalten. Module sind optional. • Userform-Objekte Der Ordner enthält Userform-Objekte, d.h. Layouts und Event-Quellen der Dialoge. Module sind optional. • Klassenmodul -Objekte Der Ordner enthält Klassenmodule. Ein Klassenmodul ist ein Objekt (mit Abstrichen) im Sinne der OOP. Module sind optional. Optionale Ordner werden beim Einfügen (Menü Einfügen oder Rechtsklick in Browserfenster) der entsprechenden Objekte (Module, Userform und Klassenmodul) angelegt. 19.10.2011 Seite 12 3.2 Bauinformatik - Teil 1 - Übungsskript / 2011 Testen eines Programms, Debugger Programme können in der IDE mit dem integrierten Debugger getestet werden. Dazu geht man wie folgt vor. Das Programm wird nach setzen eines Haltepunktes unterbrochen und kann im Einzelschrittmodus, d.h. es wird Programmzeile um Programmzeile ausgeführt durchlaufen werden. Die Belegung der lokalen Variablen oder der Zustand gewählter Testausdrucke können ausgegeben werden. Abbildung 10: VBA-IDE-Debugger Der Debugger bietet die folgenden Ausführungsoptionen. • Haltepunkt An einem Haltepunkt wird das Programm unterbrochen. Der Haltepunkt kann mit F9 oder im Menü Debuggen ein- oder ausgeschaltet werden. • Einzelschritt Mit dem Einzelschritt (F8) wird nur eine Programmanweisung ausgeführt. Mit dem Einzelschritt läuft der Debugger in Unterprogramme. • Prozedurschritt Mit dem Prozedurschritt (Shift+F8) wird nur eine Programmanweisung ausgeführt. Mit dem Prozedurschritt überspringt der Debugger Unterprogramme, d.h. die Unterprogramme werden ausgeführt ohne dass der Debugger das Programm anhält. • Cursorposition Mit der Ausführung bis zur Cursorposition (Strg+F8) kann das Programm bis zur aktuellen Cursorposition ausgeführt werden, sofern die Cursorposition in einem Programmteil liegt, der bei Ausführung durchlaufen wird. Abbildung 10 zeigt den Debugger im Testbetrieb. Haltepunkte werden als braune Punkte am linken Fensterrand des Editors angezeigt. Die aktuelle Programmposition wird in den Quellen gelb hinterlegt und zudem am linken Fensterrand durch einen gelben Pfeil markiert. E. Baeck 3. DIE VBA-IDE Seite 13 Um den Zustand eines Programms prüfen zu können bietet die IDE die folgenden Einblicke. • Direktbereich Der Direktbereich ist ein Fenster, in das vom Programm aus mit der Objektfunktion —debug.print— direkt geschrieben werden kann. In dieses Fenster können Testausdrucke geschrieben werden, wenn z.B. ein Einzelschritt-Debuggen zu aufwendig wäre (z.B. Test bei zahlreichem Schleifendurchlauf). • Lokal Um die Transparenz mit wenig Aufwand zu gewährleisten, werden im Lokal -Fenster alle lokalen Variabelen und eventuelle Programmrückgabewerte ausgegeben. • Überwachungsausdrücke Ein Überwachungsausdruck ist eine Variabel oder ein Ausdruck mit mehreren Variablen. Überwachungsausdrücke können zum bedingten Anhalten eines Programmlaufes eingesetzt werden. 19.10.2011 Seite 14 4 Bauinformatik - Teil 1 - Übungsskript / 2011 VBA-Interface Der Codegenerator der IDE verbindet Ereignisse (Klicken, Maus schieben, etc.) mit den gewünschten Programmen. Dazu ist zunächst ein Steuerelement (hier eine Schaltfläche) zu erzeugen. Die Eigenschaften des Steuerelements sind im Eigenschaftsfenster zu bearbeiten. Nach Doppelklick auf das Steuerelement wird ein Rahmen einer Klick-Ereignisfunktion im entsprechenden Tabellenordner der Tabelle, in der das Steuerelement erzeugt wurde, geschrieben. Ereignisfunktionen verknüpfen Ereignisse eines Steuerelements mit dem zu implementierenden Programmcode. 4.1 Beispiel 1 in 6 Schritten Abbildung 11: VBA-IDE Im folgenden Beispiel2 wird ein Programm implementiert, dass über eine Schaltfläche gestartet alle ganzen Zahlen aus einem vorgegebenen Intervall aufsummiert. 4.1.1 Schritt 1: Gestaltung der Oberfläche In einem ersten Schritt wird die Programmoberfläche in einer Tabelle zusammengestellt. Es sind die Felder VON und BIS anzulegen, die die Intervallgrenzen enthalten werden. Zudem ist ein Feld SUM anzulegen, in das das zu schreibende Programm den Ergebniswert eintragen wird. Auf die Vergabe der Namen (hier: VON, BIS und SUM ) Abbildung 12: Beispiel: Schritt 1 sollte nicht verzichtet werden, da das Programm Felder in einfacher Weise über Namen ansprechen kann und zudem eine Kopplung 2 Das Programm ist als Beispiel1 in der Beispiel-Sammlung zur Veranstaltung enthalten. E. Baeck 4. VBA-INTERFACE Seite 15 an das Oberflächenlayout ausgeschlossen wird. Die Schaltfläche ist mit der Werkzeugleiste Steuerelemente zu generieren. 4.1.2 Schritt 2: Gestaltung der Steuerelemente Nach dem Erzeugen der Schaltfläche (eines Steuerelements) ist diese zunächst im Entwurfsmodus, d.h. die Eigenschaften sind zu bearbeiten, Ereignisfunktionen werden automatisch durch einen Doppelklick generiert. Die Standardbezeichnung einer Schaltfläche ist CommandButton1. Dies ist der Objektname unter dem ein Objekt (hier die Schaltfläche) im Programmcode angesprochen werden kann. Die Schaltfläche soll nun ein Ereignis auslösen. Der Klick auf die Schaltfläche Abbildung 13: Beispiel: Schritt 2 soll das Programm starten. Dazu ist der schon automatisch angelegte Rahmen der Ereignisfunktion CommandButton1_Click() mit dem entsprechenden Programmcode zu füllen. Die Syntax eines Ereignisfunktionsnamens wird in VBA wie folgt aufgebaut. Der erste Teil des Namens (der Text vor dem _) ist der Name des Objekts (hier: CommandButton1). Der zweite Teil des Namens ist der Bezeichner für das Ereignis (hier: Click()). Rahmen für weitere Ereignisfunktionen werden automatisch nach Auswahl eines Ereignisses aus der Ereignisliste (siehe Abbildung 13) erzeugt. Wird z.B. das Ereignis LostFocus ausgewählt, d.h. Verlust des Eingabefokus, dann wird der Rahmen der Ereignisfunktion CommandButton1_LostFocus() erzeugt. Um die Wirkungsweise einer Ereignisfunktion zu studieren, kann in diese einfach der Aufruf einer Meldungsbox MsgBox "Meldungstext" eingetragen werden. Damit wird immer bei Auftreten des Ereignisses eine Meldungsbox in EXCEL ausgegeben. 19.10.2011 Seite 16 4.1.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Schritt 3: Generieren eines Moduls für Funktion Summe Mit einem Rechtsklick auf den Objektbrowser öffnet sich ein Menü mit der Funktion Einfügen/Modul. In den eingefügten Modul ist der Programmcode einzutragen. Der Name des Moduls wird in den Eigenschaften auf Beispiel1 abgeändert. Das noch zu implementierende Programm Summe wird nun aus der Abbildung 14: Beispiel: Schritt 3 Ereignisfunktion für das Klickereignis CommandButton1_Click() aufgerufen. Dazu ist die Zeile Beispiel1.Summe in die Ereignisfunktion einzutragen. Damit ergibt sich für die Ereignisfunktion folgender Code. Private Sub CommandButton1_Click() Beispiel1.Summe End Sub 4.1.4 Schritt 4: Das Programm Summe Um das Programm Summe zu implementieren, ist der Modulordner Beispiel1 zu öffnen und der Programmcode im Editor wie folgt einzugeben. ’ Summation aller ganzer Zahlen aus einem Zahlenintervall Public Sub Summe() Dim Dim Dim Dim ivon ibis isum i As As Integer As Integer As Integer Integer ’ Öffentliches Programm "Public Sub" ’ Deklarationen mit Dim ’ Initialisierung isum = 0 ivon = Range("VON") ibis = Range("BIS") ’ Schleife über das Intervall For i = ivon To ibis isum = isum + i Next ’ Rückgabe des Summenwerts nach EXCEL-Tabelle Range("SUM") = isum End Sub E. Baeck 4. VBA-INTERFACE Seite 17 In nachfolgender Tabelle werden die Anweisungen des Summe-Programms erläutert. Schlüssel Bemerkung Public gibt ein Unterprogramm, eine Funktion oder eine Variable frei für Zugriffe aus anderen Modulen. Sub leitet ein Unterprogramm ein. Dim explizite Deklaration der Variablen. Integer Ganzzahlige Variable, Länge 2 Byte. Range Das Range-Objekt liefert einen Zugriff auf EXCEL-Tabellenfelder. Als Argument ist die EXCEL-Adresse, z.B. "VON" oder auch "C1", anzugeben. Mit Range wird sowohl aus einem Tabellenfeld gelesen als auch geschrieben (z.B. a = Range("TEST") und Range("TEST") = a). For Mit For · · · Next wird eine Schleife implementiert. Die Laufvariable i durchläuft hierbei den Wertebereich von ivon bis ibis in Schritten von eins. End Sub schließt das Unterprogramm ab. Tabelle 3: Anmerkungen zum Programm Summe 4.1.5 Schritt 5: Programmtests Bei einem ersten Programmtest könnte die in Abbildung 15 dargestellte Fehlersituation auftreten: Die Methode Range für das Object _Global ist fehlgeschlagen, d.h. der Zugriff auf ein Tabellefeld (Lesen oder Schreiben) konnte nicht durchgeführt werden. Grund dafür ist oft die Angabe einer falschen oder unbekannten Range-Adresse. In diesem Fall wurde vergessen, die EXCEL-Tabellenfelder, auf die zugegriffen werden soll, mit einem entsprechenden Namen zu bezeichnen. Abbildung 15: Beispiel: Schritt 5 19.10.2011 Seite 18 Bauinformatik - Teil 1 - Übungsskript / 2011 Wenn in der Absturzmeldung die Funktion Debuggen aufgerufen wird, springt der Programmzeiger in die Zeile des Quellcodes, in der der Fehler aufgetreten ist: Gelbe Zeile mit dem Schlüsselwort Range. Hier führt der Aufruf zum Programmabsturz. Der Grund kann nur eine unzulässige EXCEL-Adresse sein. Lösung: Vergabe der noch fehlenden Bezeichner in der Tabelle. Abbildung 16: Beispiel: Schritt 6 4.1.6 Schritt 6: Das Ziel Um ein Programm zu testen, sind Aufgabenstellungen mit bekanntem Ergebnis zu suchen. Ein Programmtest ist dann erfolgreich, wenn eine hinreichende Anzahl von Testergebnissen reproduziert werden kann. Ein absturzfreier Durchlauf des Programms alleine ist natürlich als Test nicht ausreichend. Das Programm Summe berechnet die Abbildung 17: Beispiel: Schritt 6 Summe der ganzen Zahlen von 1 bis 7 zu 28. Auf der rechten Seite der Tabelle (siehe Abbildung 17) erfolgt zur Kontrolle eine Berechnung mit der Standard-EXCEL-Funktion Summe. Die Ergebnisse sind identisch. E. Baeck 5. ELEMENTARE ALGORITHMEN 5 Seite 19 Elementare Algorithmen Die Implementierung einfacher Algorithmen in VBA erfolgt in einer EXCEL-Tabelle. Die Eingabefelder (gelb hinterlegt) werden mit einem Namen versehen. Über diesen Namen werden die Eingabedaten aus den Feldern in den VBA-Code eingelesen (Funktion Range). Die Ergebniswerte werden ebenfalls mit der Funktion Range oder im Fall der Ausgabe einer Tabelle mit der Funktion Cells in die Tabelle geschrieben. Das Programm wird mit einer Schaltfläche gestartet. Es ist darauf zu achten, dass der ProgrammCode in einem Modul und nicht im Tabellenobjekt abgelegt wird. 5.1 Fakultät Es ist die Faktultät für eine beliebige natürliche Zahl n zu ermitteln. Die Benutzeroberfläche ist nach Abbildung 18 zu implementieren. Die Zwischenwerte der Produktbildung sind in einer Tabelle auszugeben. Die Abhängigkeit des realisierbaren Definitionsbereichs vom gewählten Datentyp (integer, long, etc.) ist zu untersuchen. n! = 1 · 2 · · · · · (n − 1) · n = n Y i (2) i=1 Abbildung 18: Oberfläche zur Fakultät und zu Binomialkoeffizienten 5.2 Binomialkoeffizient Es ist der Binomialkoeffizient für zwei beliebige natürliche Zahlen n und m zu ermitteln. Die Benutzeroberfläche ist nach Abbildung 18 zu implementieren. Die Zwischenwerte der Produktbildung sind in einer Tabelle auszugeben. Die Abhängigkeit des realisierbaren Definitionsbereichs vom gewählten Datentyp (integer, long, etc.) ist zu untersuchen. n n! = n · n − 1 · ··· · n − m + 1 = (3) m! m! · (n − m)! m 19.10.2011 Seite 20 5.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Winkel zwischen 2 Vektoren des Rn Der Winkel α zwischen 2 Vektoren ~a und ~b aus dem Rn kann mit Hilfe des Skalarprodukts wie folgt berechnet werden. ! ~a · ~b (4) α = arccos ||~a|| · ||~b|| Das Skalarprodukt zwischen den Vektoren ~a und ~b berechnet sich wie folgt. ~a · ~b = n X ai · bi (5) i=1 Die Beträge im Nenner können wie folgt mit dem Skalarprodukt berechnet werde. ||~a|| = 5.3.1 √ ~a · ~a (6) Pseudocode für Hauptprogramm Der Pseudocode für das Programm könnte wie folgt lauten. (1) Einlesen der Vektoren aus Tabelle und Prüfung der Dimensionen. (2) Berechnung des Betrages von ~a mit der Funktion a = SP rod(~a, ~a). (3) Berechnung des Betrages von ~b mit der Funktion b = SP rod(~b, ~b). (4) Berechnung des Skalarprodukts von ~a mit ~b mit der Funktion x = SP rod(~a, ~b). (5) Winkelberechnung α = arccos( 5.3.2 x ) a·b Pseudocode für Funktion SP rod Der Pseudocode für die Funktion des Skalarproduktes könnte wie folgt lauten. (1) Bestimme die Dimension der Vektoren (Muß identisch sein!). (2) Initialisiere die Summenvariable (s = 0). (3) Setze Vektorindex auf Startposition (i = 1) (4) Berechne für die Position i das Produkt p = a(i) ∗ b(i) (5) Summiere das Produkt auf die Summenvariable s = s + p (6) Inkrementiere den Vektorindex um 1 (7) Falls i ≤ n gehe zu (4). (8) Beende die Routine mit der Übergabe des Summenwertes s. E. Baeck 5. ELEMENTARE ALGORITHMEN 5.4 Seite 21 Reihenentwicklungen Im folgenden wird die Entwicklung der Funktionen sinus, cosinus und der e-Funktion diskutiert. 5.4.1 Entwicklung der Funktion sinus Es ist ein Programm zu implementieren, das die Funktion sinus mit Hilfe der Potenzreiehenentwicklung (siehe unten) berechnet. Die Eingabensgrößen sind aus der Tabelle abzugreifen, die Ergebnisgrößen sind in den Ausgabebereich der Tabelle zu schreiben. Beachten Sie bei der Umsetzung der Gleichung 7, dass die Fakultäten im Nenner der Terme zu numerischen Problemen führen können, wenn sie unabhängig vom Zähler berechnet werden. Zu beachten ist ferner (siehe Tabelle in Abbildung 19): • Der X-Wert ist aus der Tabelle in 0 zu übernehmen. • Die Genauigkeit der Approximation ist aus der Tabelle zu übernehmen. • Es ist berücksichtigen, dass das Argument der Reihenentwicklung (siehe Gleichung 7) gegebenenfalls in rad umzurechnen ist. • In den Ausgabebereich der Tabelle ist der Index des Terms, der Wert des Terms und die aktuelle Summe zu schreiben. • Bevor die Ergebniswerte in die Tabelle ausgegeben werden, sind die Zeilen des Ergebenisbereichs zu löschen. sin(x) = x − x3 x5 x2n+1 + − · · · + (−1)n ± ... 3! 5! (2n + 1)! (7) Abbildung 19: EXCEL-Tabelle zur Reihenentwicklung 19.10.2011 Seite 22 5.4.2 Bauinformatik - Teil 1 - Übungsskript / 2011 Reihenentwicklung weiterer Funktionen Analog zur Entwicklung der sinus-Funktion kann für die Funktion cosinus(x) eine Reihenentwicklung programmiert werden (siehe Gleichung 8). cos(x) = 1 − x2 x4 x2n + − · · · + (−1)n/2 ± ... 2! 4! (2n)! (8) Analog zur Entwicklung der sinus-Funktion kann für die Funktion f (x) = ex eine Reihenentwicklung programmiert werden (siehe Gleichung 9). ex = 1 + 5.5 5.5.1 x2 xn x + + ··· + ... 1! 2! (n)! (9) Newton-Verfahren Der Algorithmus des 1-dimensionalen Falls Mit dem Newton-Verfahren kann iterativ eine Nullstelle einer Funktion f (x) bestimmt werden. Hierfür sind ein Startwert x0 , eine Genauigkeit und eine maximale Iterationsanzahl nx vorzugeben. Durch Nullsetzen einer Taylor-Reihenentwicklung um den Punkt xn kann die Iterationsformel des Newton-Verfahrens abgeleitet werden. Abbildung 20: Graphische Darstellung des Newton-Verfahrens f (xn+1 ) = f (xn ) + (xn+1 − xn ) · f 0 (xn ) = 0 ⇒ f (xn ) xn+1 = xn − 0 (n = 0, 1, 2, . . . ; x0 gegeben) f (xn ) (10) Die Ableitung der Funktion f (x) kann durch den Differenzenquotienten angenähert werden. f 0 (x) = E. Baeck f (x + h/2) − f (x − h/2) z.B. mit h = 0.001 h (11) 5. ELEMENTARE ALGORITHMEN 5.5.2 Seite 23 Pseudo-Code Das Problem kann wie folgt in einem Pseudo-Code (umgangsprachliche Beschreibung) formuliert werden. 1. Wähle einen Startwert x. 2. Berechne f (x) 3. Falls |f (x)| < , dann Nullstelle gefunden. 4. Falls maximale Anzahl Iterationen erreicht, Ausgabe Fehlermeldung. 5. Berechne f 0 (x). 6. Falls |f 0 (x)| < , Ausgabe einer Fehlermeldung. 7. Nächsten x-Wert berechnen: x ⇐ x − f (x) f 0 (x) 8. Nächster Iterationsschritt mit Punkt 2. Anmerkung: Ein Problem tritt auf, wenn die Ableitung der Funktion verschwindet. Geometrisch: es gibt keinen Schnittpunkt zwischen Tangente und x-Achse. 5.5.3 Programmablaufplan Das Newtonverfahren geht aus von einem Startwert x. Dieser wird zunächst eingelesen. Die Iterationsschleife beginnt mit der Berechnung des Funktionswertes f (x). Darauf folgt die Nullabfrage. Falls der Absolutbetrag des Funktionswertes kleiner als die Genauigkeit ist, wird die Iterationsschleife abgebrochen und die Lösung ausgegeben. Es folgt die Prüfung der zulässigen Iterationsdurchläufe. Nach der Berechnung der Tangentensteigung f 0 (x) wird, falls diese nicht verschwindet, ein neuer xWert berechnet und ein neuer Schleifendurchlauf gestartet. Abbildung 21: Programmablaufplan des Newton-Verfahrens 19.10.2011 Seite 24 5.5.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Nassi-Schneidermann-Diagramm Das Nassi-ShneidermanDiagramm zeigt den linearen Fluß des Programms. Es werden keine Sprünge (Goto) durch Verbinder nahe gelegt. Im Fall des Erreichens der maximal vorgegebenen Iterationsanzahl und im Fall verschwindender Tangentensteigung wird das Programm direkt mit einer entsprechenden Meldung abgebrochen. Abbildung 22: NS-Diagramm des Newton-Verfahrens 5.5.5 Die Oberfläche In den gelb hinterlegten Tabellenfeldern C3-C5 werden die Eingangsgröße, der Startwert x, die maximal zulässige Anzahl der Iterationen und die gewünschte Genauigkeit eingegeben. Mit der Schaltfläche wird das Programm gestartet. In den Ausgabefeldern C8-C10 werden die Ergebnisgrößen, die eventuell gefundene Nullstelle, der durchlaufenen Iterationen und eine Kommentierung des Iterationsverlaufs ausgegeben. Abbildung 23: EXCEL-Tabelle zum Programm Im unteren Teil der Tabelle werden die Ergebnisse der einzelnen Interationsschritte ausgegeben. E. Baeck 5. ELEMENTARE ALGORITHMEN 5.5.6 Seite 25 Animation des Verfahrens Die animierte Darstellung des Newtonverfahrens zeigt die Annäherung an die Nullstelle durch konsequentes Verfolgen der Funktione (blaue Linie) entlang ihrer Tangente (rote Kurve). Start der Animation durch Anklicken Abbildung 24: Animation des Newton-Verfahrens. 19.10.2011 Seite 26 6 Bauinformatik - Teil 1 - Übungsskript / 2011 Elementare Sortiert-Algorithmen Einfache Sortieralgorithmen können problemlos zum Sortieren kleiner Datenmengen eingesetz werden. Da der Sortieraufwand zumeist in quadratischer Ordnung O(n2 ) der zu sortierenden Datensätze anwächst, sind große Datenmengen i.A. mit diesen Algorithmen nicht mehr wirtschaftlich zu sortieren. Im folgenden werden zwei der einfachen Sortieralgorithmen dargestellt, • Select-Sort oder Auswahlsortierung und • Bubble-Sort 6.1 Select-Sort Select-Sort wählt aus einer zu sortierenden Menge das größte Element aus und tauscht es mit dem Element der ersten Position. Aus den verbleibenden Elementen wählt er wiederum das größte Element aus und tauscht es mit dem Element der zweiten Position. Dieses Verfahren wird solange fortgesetzt, bis die zu durchsuchende Menge auf ein Element zusammen geschrumpft ist. Der so implementierte Algorithmus ist offensicht von quadratischer Ordnung, d.h. O(n2 ), da in einer Schleife alle Positionen neu besetzt werden müssen und in dieser in einer inneren Schleife der Datenbestand - zwar nicht zur Gänze durchlaufen wird, um das aktuell größte Element zu bestimmen. Abbildung 25: SelectSort: SORTIERANGS In Abbildung 25 wird das Wort SORTIERANGS alphabetisch sortiert. In jedem Schritt wird aus der aktuellen Sortiermenge der kleinste Buchstabe im Sinne des Alphabets gesucht. Im ersten Schritt wird das A gefunden und mit dem Buchstaben der ersten Position S getauscht. Der erste Buchstabe der aktuellen zu durchsuchenden Menge wird fett berandet dargestellt. Der kleinste Buchstabe wird farbig markiert. In nachfolgenden Zeile wird zum einen der Buchstabentausch dargestellt, zum anderen wird die neue Suchmenge und ihr kleinster Buchstabe dargestellt. Um die einzelnen Suchschritte visuell abzusetzen wird für jeden Such- und dazugehörigen Tauschschritt eine eigene Hintergrund-Farbe gewählt. E. Baeck 6. ELEMENTARE SORTIERT-ALGORITHMEN 6.2 Seite 27 Bubble-Sort Die Idee des Bubble-Sort-Algorithmuses folgt der Vorstellung von aufsteigenden Luftblasen in einer Flüssigkeit. Vom letzten Element an wird in einer inneren Schleife vom ersten Element an bis zum betrachteten dann eine Vetauschung ausgeführt wenn das Element der inneren Schleife größer (bzw. kleiner)3 ist als das betrachtete. So steigen die größeren (bzw. kleineren) Element nach vorne auf wie Luftblasen in einer Flüssigkeit (Bubble-Sort). Im Vergleich zu SelectSort benötigt BubbleSort einen unnötig hohen Aufwand des Vertauschens. 3 Abhängig von der Sortierrichtung steigt entweder das kleinere oder größere Element auf Richtung Platz 1. 19.10.2011 Seite 28 7 Bauinformatik - Teil 1 - Übungsskript / 2011 Arbeiten mit Dateien 7.1 Dateioperationen für sequentiellen Zugriff Die Datei wird geöffnet unter Vorgabe des Dateinamens und des Verarbeitungskenners (Input, Output, Append ). Die Zugriffe auf die Datei erfolgen unter Vorgabe der Kanalnummer. In nachfolgender Tabelle werden wesentliche Dateifunktionen zusammengefaßt. Funktion Beschreibung Beispiel Open Öffnen einer Datei. Open "bsp.txt" For Input As #1 Input Einlesen aus einer Datei. Input #1, x, y Write Schreiben ı́n eine Datei. Write #1, x, y Close Schließen der Daten. Close #1 Input Line Einlesen einer Datenzeile aus Textdatei. Input Line #1, s EOF Dateiende erkennen. Do While Not EOF(1) Die EXCEL-Anwendung liefert einen Standarddialog zur Suche einer Datei. Der Aufruf dieses Dialogs wird in nachfolgendem Code dargestellt. Die im nachfolgenden Beispiel dargestellte Funktion wird als Steuerprogramm zur Berechnung des Torsionsträgheitsmomentes nach der Brendt’schen Formel eingesetzt (siehe Gleichung 12). Im 2. Schritt wird die Methode GetOpenFilename des Application-Objekts4 aufgerufen. Die Methode startet den allgemeinen Windows-Datei-Öffnen-Dialog. Als Rückgabewert liefert die Methode den Namen der gewählten Datei. Wird der Dialog vom Anwender abgebrochen, so wird der String Falsch zurückgegeben.5 ’ Dateinamen ermitteln Private Sub CommandButton1_Click() ’ 1: Initialisierung Call Brendt.Init ’ 2: Dateinamen festlegen datei$ = Application.GetOpenFilename( _ fileFilter:="Textdateien (*.txt),*.txt") ’ 3: Starten der Berechnung If Not datei$ = "Falsch" Then Range("Datei") = datei$ ’ Einlese der Datei und Berechnung Call Brendt.ProfilLesen(datei$) 4 Das Objekt Application, siehe auch OOP, stellt alle Objekte der EXCEL-Anwendung zur Verfügung. Objekt der EXCEL-Anwendung sind z.B. die Listen der Tabellen und Diagramme, sind auch die Range-Objekte, die die Kommunikation mit den Tabellenfeldern ermöglicht. 5 Mit der Rückgabe Falsch im Fall des Abbruchs ist es unzulässig eine Datei mit dem Namen Falsch anzusprechen, was i.A. kein Problem sein dürfte. E. Baeck 7. ARBEITEN MIT DATEIEN Seite 29 Call Brendt.ProfilBerechnen End If End Sub 7.2 Torsionsträgeheitsmoments nach 2. Brendt’scher Formel In einer Datei wird eine beliebige, konvexe Kontur eines Profils durch Punkte auf der Mittelfläche im üblichen y-z-Koordinatensystem beschrieben (x-Achse ist Profillängsrichtung). Zu jedem Punkt wird als dritter Wert die Dicke des Profils am Ort des Punktes angegeben. Das Programm zur Berechnung des Torsionsträgheitsmomentes nach der 2. Brendt’schen Formel erhält die folgenden Optionen. • Einlesen und Speichern der Datei in dynamisch angelegten Feldern (Arrays), wobei die Information eines Punktes in einer benutzerdefinierten Strukur (TYPE/END TYPE) gehalten werden soll. Um eine zyklische Profilbeschreibung zu erleichtern, sind die Daten des ersten Punktes als zusätzlicher der Punktliste anzuhängen. • Ausgabe der Daten des Feldes in einer Tabelle. Die Altdaten werden zunächst mit der Funktion Löschen aus der Tabelle entfernt. • Ausgabe der Profilkontur in einem Diagramm in Form eines X-Y-Plots. • Berechnung des Torsionsträgheitsmoments mit Hilfe der 2. Brendt’schen Formel. IT = (2 · Am )2 H ds t (12) Im Fall dünnwandiger Profile kann die Gleichung 12 wie folgt vereinfacht werden. PN Li zu berechnen, wobei 1. Zunächst ist das Linienintegral durch die Summe i=1 ti p Li = (yi − yi+1 )2 + (zi − zi+1 )2 und ti = 0.5 · (ti + ti+1 ). 2. Die Fläche der Kontur kann mit der folgenden Formel zur Bestimmung einer Polgonfläche ermittelt werden. Am = N X yi · zi+1 − zi · yi+1 i=1 2 (13) mit: yN +1 = y1 , und zN +1 = z1 19.10.2011 Seite 30 8 Bauinformatik - Teil 1 - Übungsskript / 2011 Das Clapeyron-Problem Mit der Gleichung nach Clapeyron können die Stützmomente eines n-Feldträgers (Durchlaufträger) berechnet werden. Die Herleitung der Gleichung6 aus dem Kraftgrößenverfahren wird in Abschnitt A dargestellt. Der Abschnitt zeigt exemplarisch die wesentlichen Schritte der Entwicklung eines Berechnungsprogramms mit moderner Eingabeoberfläche und entsprechender Datenhaltung. 8.1 Motivation In diesem Abschnitt wird die Entwicklung eines Programms zur Berechnung der Stützmomente eines n-Feld-Durchlaufträgers dargestellt. Es werden als Belastungen Streckenlasten, Punktlasten und Punktmomente vorgesehen, die beliebig auf den Feldern des Trägers positioniert werden können. Die Entwicklung erfolgt den Schritten: 1. Gestaltung der Eingabe in einer Benuzteroberfläche. 2. Modellierung der Datenstrukturen und Visualisierung im ER-Modell. 3. Algorithmus zur Generierung der Modell-Datenstrukturen. 4. Algorithmus zum Aufbau des linearen Gleichungssystems (A · x = b). 5. Cholesky-Algorithmus zur Zerlegung der Matrix A = L · LT . 6. Berechnung der Stützmomente durch Vorwärts- Rückwärtseinsetzen. 7. Ausgabe der Ergebnisgrößen in der Benutzeroberfläche. 8.2 Oberflächenlayout und Eingabe Als Eingabeoberfläche wird eine EXCEL-Tabelle eingesetzt, in der die Felder bzw. die Belastungen der Felder in Listenform eingetragen werden. Die Eingabetabelle orientiert sich ausschließlich an den Bedürfnissen des Anwenders und enthält keinerlei Daten, die nur durch die Organisation der Daten im Programm (Datenstrukturen) betreffen. Generell sollte sich die Eingabeoberfläche eines Programms nur an der Sicht des Anwenders orientieren. So sollten keine für die Gestaltung der Datenstruktur wichtigen Parameter als Eingabeparameter vorgesehen werden, da deren Notwendigkeit dem Anwender kaum vermittelbar ist. Die Anzahl der Felder z.B. ergibt sich aus ihrer Beschreibung. Die Vorgabe der Anzahl der gewünschten Felder wäre somit für den Anwender eine redundante Eingabe. Die Anzahl der Felder ist für die Dimensionierung der Feldvariabeln erforderlich und ist vom Programm aus den Eingaben des Anwenders abzuleiten. 6 Die Gleichung von Clapeyron wird auch 3-Momentengleichung genannt. E. Baeck 8. DAS CLAPEYRON-PROBLEM Seite 31 Im Vorschlag der Eingabe werden die Felder von links nach rechts eingegeben. Die Feldnummerierung ergibt sich automatisch aus der Reihenfolge. Abbildung 26: Eingabe Oberfläche des Programms 8.2.1 Feldbeschreibung Die Felddaten können in Form einer Liste eingegeben werden. Die Reihenfolge entspricht der Feldreihenfolge vom Festlager (links) hin zum Gleitlager (rechts), siehe z.B. Abbildung 43. Pro Feld werden • die Feldlänge in [cm] und • das Verhältnis der Flächenträgheit zur Referenzträgheit Ic eingegeben. Das Import-Programm liest die Datensätze von oben nach unten aus der Tabelle und schreibt die erfassten Daten in ein Feld aus entsprechenden Datenstrukturen. Die Dimensionierung ergibt sich aus der Anzahl der Datensätze. 8.2.2 Lastbeschreibung Die Lastdaten können beliebig in Form einer Liste eingegeben werden. Ein Lastdatensatz enthält die folgenden Daten. • Die Lastfallnummer, Wahl der rechten Seite (siehe Abschnitt D). • Die Feldnummer beschreibt den Ort der zu erfassenden Last. • Der Belastungstyp: – Typ 1, die Streckenlast Parameter: Lastordinate q, Abszisse des Lastschwerpunktes a und Lasteinleitungslänge c. – Typ 2, die Punktlast Parameter: Lastordinate P , Abszisse der Lasteinleitung a. – Typ 3, das Punktmoment Parameter: Lastordinate M , Abszisse der Lasteinleitung a. • Lastordinate für Typ 1, q, in [kN/cm], für Typ 2, P , in [kN] und für Type 3 M in [kNcm]. Dieses Eingabefeld und alle weiteren beschreiben die Details der gewünschten Last. 19.10.2011 Seite 32 Bauinformatik - Teil 1 - Übungsskript / 2011 • Der Parameter a beschreibt den Abstand des Lastschwerpunktes vom linken Lager in [cm] (für alle Typen relevant). • Der Parameter c beschreibt die Länge der Lasteinleitung in [cm] (nur für Typ 1 relevant). 8.3 ER-Modell der Datenstruktur Das ER-Modell (nach Chen siehe Abschnitt B) der Datenstruktur des Clapeyron-Problems besteht aus zwei Teilen, dem Datenmodell der Struktur und dem Datenmodell der Belastung. In den Diagrammen zum Struktur- und Lastdantenmodell des Clapeyron-Problems werden Container -Objekte kursiv geschrieben. Container -Objekte sind Objekte, die eine beliebige Anzahl von Objekten aufnehmen können. In diesem Beispiel werden einfache Datenfelder eingesetzt. In VBA werden diese durch die Vorgabe des Index-Bereiches vereinbart. Beispiele 1: Statische Deklaration eines Containers für 20 Felder Dim FA(1 to 20) As Feld Beispiele 2: Dynamische Deklaration eines Containers für n Felder Dim FA() As Feld ... n = ... Redim FA(1 to n) 8.3.1 ER-Modell der Struktur Das System des Durchlaufträgers besteht aus mehreren Feldern. Diese werden in dem Objekt Felder zusammen gefaßt. Die Anzahl der Felder ist theoretisch Unbeschränkt, somit eine 1-n-Beziehung. Ein Feld hat die Attribute Länge und Trägheit (siehe Abbildung 27). Abbildung 27: ER-Modell der Struktur Aufgabe 8.3.1: Es sind dem ER-Modell entsprechende Datenstrukturen (Schlüsselwort Type ... End Type) in VBA zu entwickeln. E. Baeck 8. DAS CLAPEYRON-PROBLEM 8.3.2 Seite 33 ER-Modell der Belastung Das Datenmodell der Belastung geht aus von einem Container (Liste oder Feld) der Lastfälle. Der Container kann beliebig viele Lastfälle aufnehmen (1-n-Beziehung). Jeder Lastfall enthält wiederum drei Container. Der erste Container enthält die Streckenlasten, der zweite die Punktbelastungen und der dritte die Punktmomente. Jeder dieser drei Beziehungen ist eine 1-n-Beziehung, da jeder Container beliebig viele Lasten aufnehmen kann. Ein Lastfall hat das Attribut Nr, er weiß sozusagen, wie er heißt. Die Lastarten haben als Attribute ihre Parameter, Lastordinate, Lastabszisse und die Streckenbelastung hat zudem das Attribut der Lasteinleitungslänge. Abbildung 28: ER-Modell der Belastung Aufgabe 8.3.2: Es sind dem ER-Modell entsprechende Datenstrukturen (Schlüsselwort Type ... End Type) in VBA zu entwickeln. 19.10.2011 Seite 34 8.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Aufbau der Datenstruktur In diesem Abschnitt wird ein Algorithmus zum Aufbau der Datenstrukturen für System und Belastung entwickelt. 8.4.1 Die Datenstruktur des Systems Die Daten eines Feldes werden in der Struktur (Type) Feld abgespeichert. Als Container wird zunächst ein Datenfeld eingesetzt. Dieses wird dynamisch an die zu speichernde Datenmenge angepaßt (dynamisches Allokieren). Da die Anzahl der Felder nicht explizit festgelegt wird, ist diese zunächst aus den Eintragungen der Tabelle zu ermitteln. Die ausgefüllten Tabellenfelder der Spalte Feldlänge (siehe Abbildung 26) werden im ersten Durchlauf gezählt, um den Container dimensionieren zu können. Wenn die Feldanzahl feststeht, wird der Container entsprechend dimensioniert. In einem zweiten Durchlauf über die Tabelle wird die Feldlänge und das Trägheitsverhältnis eines Abbildung 29: Aufbau der Strukturdaten Feldes ausgelesen und in die Feldstruktur eingetragen. Die Feldstruktur wird in den Container aufgenommen. Aufgabe: Es ist ein Programm zu implementieren, dass aus der Tabelle der Abbildung 26 die Daten der Felder ausliest und diese in einem Container passender Größe abspeichert. Hinweis: Der Container wird mit dem Schlüsselwort Dim [Bezeichnung]() As [Type] und ReDim [Bezeichnung](1 to nFeld) angelegt. Der Zugriff auf die Tabellenfelder erfolgt mit dem Objekt Cells (i,j), wobei Cells (1,1) der Tabellenadresse A1 entspricht. E. Baeck 8. DAS CLAPEYRON-PROBLEM 8.4.2 Seite 35 Die Datenstruktur der Belastungen Der Aufbau der Datenstrukturen für die Belastungen erfolgt in drei Durchläufen. In jedem Durchlauf werden die Datenfelder neu Eingelesen und nach anderen Kriterien ausgewertet. Im ersten Durchlauf werden die extremalen Lastfallnummern ermittelt (siehe Abbildung 30). Im Intervall zwischen den extremalen Lastfallnummern wird ein Indexvektor aufgestellt, der mit der Lastfallnummer indiziert wird. Abbildung 30: Ermitteln extremaler Lastfallnummern Aufbau des Lastfall-Indexvektors In den Lastfall-Indexvektor ist in einem zweiten Durchlauf • die gefundene Lastfallnummer, • die Anzahl der Streckenlasten zu diesem Lastfall, • die Anzahl der Punktlasten zu diesem Lastfall und • die Anzahl der Punktmomente zu diesem Lastfall einzutragen. Das Eintragen erfolgt durch schrittweises Hochzählen der gefundenen Lastdaten (siehe Abbildung 31). Abbildung 31: Ermitteln der Lastdatenanzahlen 19.10.2011 Seite 36 Bauinformatik - Teil 1 - Übungsskript / 2011 Aufbau der Datenstruktur Der Lastfall-Container wird im Bereich der gefundenen Lastfallnummern angelegt, d.h. ein Lastfall wird direkt über seine Nummer angesprochen, auf eine kompakte Speicherung wird hier verzichtet, da die Datenstruktur der Belastung abgesehen von der Lastfallnummer zunächst nur leere Container für die Lastdaten enthält. Abbildung 32: Aufbau der Last-Datenstruktur In einer Schleife über den Lastfall-Indexvektor ILF wird für jeden vorhandenen Lastfall • die Lastfallnummer aus ILF übertragen, • falls Streckenlasten vorhanden, ein Container ausreichender Größe für diese dimensioniert, • falls Punktlasten vorhanden, ein Container ausreichender Größe für diese dimensioniert und • falls Punktmomente vorhanden, ein Container ausreichender Größe für diese dimensioniert. Wie viele Streckenlasten, Punktlasten und Punktmomente vorhanden sind, ist dem entsprechenden Zähler des Lastfall-Indexvektors zu entnehmen (ILF(lf).sl, ILF(lf).pl und ILF(lf).pm). Einlesen der Lastdaten Bevor die Lastdatensätze eingelesen werden können, werden die Lastdatenzähler im Lastfall-Indexvektor zurück gesetzt (d.h. auf 0 gesetzt). Die Einleseschleife läuft sodann über alle Lastdatensätze. Es werden zunächst Lastfallnummer und Lasttyp eingelesen. Der Zähler des vorliegenden Lastfalls bzw. des vorliegenden Lasttyps wird inkrementiert, um ein fortlaufendes Einspeichern der Lastdaten in den Container zu ermöglichen. Mit diesem inkrementierten Zähler wird sodann der Lastdaten-Container (Streckenlast, Punktlast oder Punktmoment) indiziert. Die Lastdaten werde aus der Tabelle mit der Funktion Cells gelesen und in den entsprechenden Container übertagen (siehe Abbildung 33). Abbildung 33: Einlesen der Lastdaten E. Baeck 8. DAS CLAPEYRON-PROBLEM 8.5 Seite 37 Aufbau des Linearen Gleichungssystems In diesem Abschnitt wird aus den Daten der Datenstrukturen der Felder und Lasten (siehe Abschnitt 8.4) das lineare Gleichungssystem entwickelt. 8.5.1 Aufbau der Koeffizientenmatrix Die Koeffizienten-Matrix A eines n-Feldträgers (siehe Gleichung 33) hat die Dimension (n − 1) ⊗ (n − 1) und ist zudem (siehe Gleichung 28) • symmetrisch mit • Bandstruktur der Bandweite 17 . Für einen 5-Feldträger der Feldlängen l1 bis l5 ergibt sich die folgende Koeffizienten-Matrix. 2 · (l1 + l2 ) l2 0 0 l2 2 · (l2 + l3 ) l3 0 A= (14) 0 l3 2 · (l3 + l4 ) l4 0 0 l4 2 · (l4 + l5 ) Da die Symmetrie der Matrix A während der Zerlegung erhalten bleibt (siehe Abschnitt D.3), kann auf das Abspeichern der oberen Hälfte der Matrix A verzichtet werden. Im Fall der Clapeyron’schen Gleichung ist zudem nur die erste Nebendiagonale besetzt, d.h. es ist nur erforderlich, die Diagonale und die erste Nebendiagonale von A zu speichern. Eine kompakte Speicherung einer symmetrischen Bandmatrix mit Bandbreite m erfordert die folgende Indexsubstitution. ai,k → ai,k−i+m+1 (k ≤ i) (15) Mit der Indexsubstitution (15) folgt für die Matrix (14) 0 2 · (l1 + l2 ) l2 2 · (l2 + l3 ) A= l3 2 · (l3 + l4 ) l4 2 · (l4 + l5 ) 7 (16) Die Bandweite einer Matrix ist gegeben durch die Anzahl der besetzten Nebendiagonalen. 19.10.2011 Seite 38 Bauinformatik - Teil 1 - Übungsskript / 2011 Der erforderliche Speicher für die Koeffizientenmatrix eines n-Feldträger ergibt sich somit zu (n − 1) · 2 (siehe (16)). Die Besetzung der Matrix folgt aus (16). In die erste Spalte werden die Feldlängen geschrieben, wobei die erste Feldlänge durch 0 erstetzt wird. In der zweiten Spalte steht die zweifache Summe aufeinander folgender Felder. Der Algorithmus des Aufbaus wird in Abbildung 34 Abbildung 34: Aufbau der Koeffizientenmatrix dargestellt. Die Länge des i-ten Feldes li , wird aus dem Feld-Container abgegriffen und mit dem Trägheitsverhältnis skaliert FA(i).L/FA(i).dI (siehe Abschnitt A) Durch die kompakte Speicherung der Matrix reduziert sich der erforderliche Speicher wie folgt. Akompakt Akomplett = 2 · (n − 1) 2 = 2 (n − 1) n−1 (17) Im betrachteten Beispiel des 5-Feldträgers reduziert sich der erforderliche Speicherplatz auf 1 2 5−1 = 2 = 50%. Im Fall eines 101-Feldträgers beträgt der erforderliche Speicherplatz bereits 1 2 101−1 = 50 = 2% der Gesamtmatrix. 8.5.2 Aufbau der Lastvektoren Die Lastvektoren werden der Einfachheit halber nicht dicht sondern im Intervall [lfmin , lfmax ] angelegt. Ob ein Lastvektor Lasten enthält oder nicht ergibt sich aus der Summe der Lastdatensätze eines Lastfalls (siehe Lastfall-Indexvektor Abschnitt 8.4.2). Für die drei Lastarten werden Lastgeneratoren implementiert. Die generierten Lastdaten werden in den Lastvektor aufsummiert. Nach [1] ergibt sich für den i-ten Eintrag in den Lastvektor, d.h. für das rechte Stützmoment des i-ten Feldes8 . • für eine Streckenlast aus linksseitigem Feld bi,l = −Ri−1 · li−1 1 = −q · a · c 1 − α − · γ 2 4 2 · li−1 (18) • für eine Streckenlast aus rechsseitigem Feld 1 bi,r = −Li · li = −q · b · c 1 − β 2 − · γ 2 · li 4 8 Es werden die folgenden Abkürzungen verwendet: α = E. Baeck a b l−a c ,β= = und γ = l l l l (19) 8. DAS CLAPEYRON-PROBLEM Seite 39 • für eine Punktlast aus linksseitigem Feld9 bi,l = −Ri−1 · li−1 = −P · a · b (1 − α) (20) • für eine Punktlast aus rechtsseitigem Feld bi,r = −Li · li = −P · a · b (1 − β) (21) • für ein Punktmoment aus linksseitigem Feld10 bi,l = −Ri−1 · li−1 = M L · 1 − 3 · α2 · li−1 (22) • für ein Punktmoment aus rechtsseitigem Feld bi,r = −Li · li = −M L · 1 − 3 · β 2 · li 9 10 (23) Die Feldlängen kürzen sich aus den Termen für Punktlasten. M L ist ein linksdrehendes (mathematisch positives) Moment. Der Vorzeichenwechsel folgt aus der Symmetrie. 19.10.2011 Seite 40 9 Bauinformatik - Teil 1 - Übungsskript / 2011 VBA-Objekte Objekte oder Klassen im Sinne der OOP (objektorientierten Programmierung) werden in VBA mit Klassenmodul bezeichnet. Die Klassenbestandteile (siehe UML in Abschnitt C) bestehen aus den folgenden Komponenten. • Die Bezeichnung des Klassenmoduls ist die Klassenbezeichnung. • Globale Variablen eines Klassenmoduls sind die Klassenattribute. • Die Funktionen und Programme in einem Klassenmodul sind die Methoden der Klasse. Auf alle Mechanismen der Vererbung von Klassen (Generalisierung, Polymorphismus), die in den meisten Programmiersprachen der OOP implementiert werden, wird in VBA aus Sicherheitsgründen verzichtet. 9.1 Konstruktor und Destruktor Jeder Klassenmodul hat die folgenden Methoden.11 • Der Konstruktor Class Initialize Diese Methode wird aufgerufen, wenn eine Instanz des Klassenmoduls mit dem new Operator (set s = new Stab) erzeugt wird. Im Beispiel wird das Objekt Stab initialisiert. Es werden Fläche und E-Modul vorbelegt. Es werden die Instanzen der KnotenKlassenmodul für die Stabenden erzeugt. Private Sub Class_Initialize() Set Ka = new Knoten Set Kb = new Knoten Fl = 0# Em = 210000# End Sub • Der Destruktor Class Terminate Wenn eine Instanz eines Klassenmoduls zerstört wird, d.h. aus dem Speicher entfernt wird, wird zunächst diese Methode aufgerufen, um dem Programm die automatisierte Möglichkeit zu bieten, Aufräumarbeiten auszuführen. Das Zerstören einer Instanz erfolgt mit dem nothing-Operator (set s = nothing). Im nachfolgenden Beispiel werden vor dem Entfernen eines Stab-Objekts dessen beide Knoten-Instanzen entfernt.12 Private Sub Class_Terminate() Set Ka = nothing Set Kb = nothing End Sub 11 Die Beispiele dieses Abschnitts beziehen sich auf die Objekte Knoten und Stab des Abschnitts 9.4). Da in VBA nur dann ein Objekt vernichtet wird, wenn alle Verweise auf nothing gesetzt werden, können alle Knoten-Instanzen durch den dargestellten Destruktor vernichtet werden. 12 E. Baeck 9. VBA-OBJEKTE 9.2 Seite 41 Vektoren und Matrizen Vektoren- und Matrizen können im Sinne der OOP als Klassenmodule implementiert werden. Abbildung 35 zeigt hierfür ein UML-Klassendiagramm. Im Konstruktor (Class Initialize) werden StandardDimensionen gesetzt. Im Beispiel des Anhangs wird mit n = 3 das Feld des Vektors bzw. das Feld der Matrix x dimensioniert. Der Vektor wird als Einheitsvektor in x-Richtung initialisiert (1, 0, 0). Abbildung 35: Vektor- und Matrix-Objekte 9.2.1 Methoden des Klassenmoduls Vektor Methode Anmerkung Laenge Berechnung und Rückgabe der Vektorlänge N orm Normierung der Vektor-Instanz Rot Multiplikation des Vektors mit einer Matrix-Instanz SP rod Skalare Multiplikation mit anderer Vektor-Instanz SetX Belegen der Vektor-Elemente (Übergabe mit Feld) GetX Lesen der Vektor-Elemente (Übergabe mit Feld) Xi Lesen einer Vektor-Komponente List Kontrolausgabe der Vektor-Attribute 9.2.2 Methoden des Klassenmoduls Matrix Methode Anmerkung SetX Belegen der Matrix-Elemente (Übergabe mit Feld) GetX Lesen der Matrix-Elemente (Übergabe mit Feld) GetK Lesen eines Matrixelements List Kontrolausgabe der Matrix-Attribute 19.10.2011 Seite 42 9.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Die Containerklasse Collection Mit dem in VBA implementierten Klassenmodul Collection wird die Möglichkeit geschaffen, auf einfache Weise Instanzen von Klassenmodulen in Listen-Form abzuspeichern.13 Die gespeicherte Instanz kann optional über den Index oder über einen freiwählbaren Schlüssel angesprochen werden. Die Collection bietet hierbei ein automatisches Speichermanagement, das jederzeit für ausreichenden Speicher sorgt. Die Collection bietet die foldenden Methoden.14 • Add Mit Add kann eine Instanz einer Klasse in die Liste übernommen werden. Parameter Anmerkung Item Zeiger auf Instanz eines Objekts Key Objektbezeichnung der Instanz Bef ore Objektbezeichnung für Einfügen vor Af ter Objektbezeichnung für Einfügen nach Beispiel: Das folgende Beispiel zeigt das Erzeugen zweier Instanzen des Klassenmoduls Knoten. Die Adressen der Instanzen werden in der Collection unter den Bezeichnungen Knoten 1 und Knoten 2 abgespeichert. dim Kn as Knoten set Kn = new Knoten Liste.Add item:= Kn key:="Knoten 1" set Kn = new Knoten Liste.Add item:= Kn key:="Knoten 2" • Item Mit der Methode Item wird die Adresse einer Instanz eines Klassenmoduls aus der Collection gelesen. Die Methode hat die folgenden Parameter. Parameter Anmerkung Index Index der zu lesenden Instanz oder dessen Bezeichnung (d.h. key), siehe Add -Methode. Beispiel: In nachfolgendem Beispiel wird aus der Collection der Bezeichnung Liste die Adresse der 2. Instanz gelesen. Hierfür kann optional auf das explizite Notieren der Methodenbezeichnung Item verzichtet werden (Variante 2). In der 3. Variante wird die Adresse der Instanz über deren Bezeichnung gelesen. In allen Varianten wird die gelesene Adresse der ObjektVariablen Kn mit dem Operator Set zugewiesen.15 13 Die Beispiele dieses Abschnitts beziehen sich auf die Objekte Knoten und Stab des Abschnitts 9.4). Bedauerlich an der Implementierung der Collection ist, dass auf alle Fehlerprüfungen verzichtet wurde, d.h. es gibt keine Fehlerkenner in der Rückgabe. Wird z.B. auf ein nicht vorhandenes Element zugegriffen, stürzt das Programm ab, wenn nicht durch einen Fehlerhandler der Fehler abgefangen wird, was eine für diese Situation recht aufwendige Mimik erfordert. 15 Kurioserweise wurde bei der Implementierung der Collection auf eine Inquire-Methode verzichtet, mit deren Hilfe die Existenz einer Instanz in der Collection ermittelt werden könnte. 14 E. Baeck 9. VBA-OBJEKTE dim set set set Kn Kn Kn Kn Seite 43 as Knoten = Liste.Item(2) = Liste(2) = Liste.Item("Knoten 2") • Remove Mit der Methode Remove wird eine in der Collection gespeicherte Instanz-Adresse gelöscht. Es wird nur der Eintrag der Adresse gelöscht, nicht die Instanz selbst.16 Parameter Anmerkung Index Index der zu löschenden Instanz oder dessen Bezeichnung (d.h. key), siehe Add -Methode. Beispiel: In nachfolgendem Beispiel wird zunächst der 1. Eintrag aus der Collection entfern. Anschließend wird eine Instanz mit der Bezeichnung Knoten 2 entfernt. Liste.Remove(1) Liste.Remove("Knoten 2") • Count Mit der Methode Count wird die Anzahl der in der Collection gespeicherten InstanzAdressen zurückgegeben. Beispiel: In nachfolgendem Beispiel werden in einer Schleife alle Einträge aus einer Collection entfernt. Dies erfolgt durch n-faches Löschen des ersten Eintrages, da nach Löschen eines Eintrages die Indizierung lückenlos aktualisiert wird, d.h. der vormals 2. Eintrag der Liste rückt auf die 1. Stelle vor, nachdem der 1. Eintrag entfernt wurde. Die Anzahl der gespeicherten Einträge n liefert die Methode Count. n = Liste.Count for i=1 to n Liste.Remove(1) next 16 Eine Instanz wird dann gelöscht, wenn allen Objektvariablen, die auf diese Instanz verweisen, der Wert nothing zugewiesen wird. 19.10.2011 Seite 44 9.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Datenstruktur eines Stabwerks Ein Stabwerk besteht aus n-Stäben. Ein Stab hat die Attribute E-Modul und Querschnittsfläche (beide double). Die Geometrie eines Stabes wird beschrieben durch den Start- und den Endknoten. Als Attribut erhält eine StabInstanz den Verweis (Objektvariable) auf zwei KnotenInstanzen, d.h. eine Knoten-Instanz wird i.A. von mehreren Stab-Instanzen referenziert. Abbildung 36: Datenstruktur eines Stabwerks Der in Abbildung 37 dargestellte Rahmen ist auf der Grundlage des in Abbilung 36 dargestellten UMLDiagrammes zu implementieren. Die Daten des Rahmens sind aus der in Abbildung 38 dargestellten Tabelle auszulesen. Nach Aufbau der Datenstruktur sind die Rahmendaten mit der Funktion List im Ausgabebereich der Tabelle anzulisten. Die Knotendaten sind in der Collection KListe, die Stäbe in der Collection SListe abzuspeichern. E. Baeck Abbildung 37: Rahmenbeispiel 9. VBA-OBJEKTE 9.4.1 Seite 45 Die Oberfläche Mit der Klassen-Methode Verschieben ist der Rahmen mit einer zweiten Ereignisfunktion um den vorgegebenen Verschiebungsvektor zu verschieben. Das Ergebnis der Verschiebung ist erneut in der Tabelle auszugeben. Zudem ist mit der Stab-Methode Laenge die Stablänge zu ermitteln und diese in der entsprechenden Tabellenspalte einzutragen. 9.4.2 Methoden des Punktes Abbildung 38: Eingabetabelle Für das Punkt-Objekt sind die folgenden Methoden zu implementieren. • Verschieben Auf die Koordinaten des Knotens wird der Verschiebungsvektor v aufaddiert. x x vx ⇐ + y y vy (24) • Drehen Auf den Ortsvektor des Knotens wird die Drehmatrix zum Winkel ϕ aufmultipliziert.17 x + cos(ϕ) − sin(ϕ) x ⇐ · (25) y + sin(ϕ) + cos(ϕ) y • Listen Die Ausgabe der Knotenattribute x und y in ein Tabellenfeld erfolgt zweckmäßig unter Vorgabe des Tabellenadressenursprungs (Spalten- und Zeilennummer für die Funktion Cells). 9.4.3 Methoden des Stabes Für den Stab sind die folgenden Methoden zu implementieren. • Länge l= p (xa − xb )2 + (ya − yb )2 (26) • Verschieben Es sind nach (24) beide Knoten des Stabes zu verschieben. 17 von Generell sind die Winkel in Winkelfunktionen der Programmiersprachen in rad einzusetzen. Die Umrechnung ◦ in rad erfolgt unter Ausnutzung der Rechengenauigkeit mit der Skalierung atan(1)/45◦ . 19.10.2011 Seite 46 Bauinformatik - Teil 1 - Übungsskript / 2011 • Drehen Es sind nach (25) beide Knoten des Stabes zu drehen. • Listen Die Ausgabe der Stab- und Knotenattribute in eine Tabelle erfolgt zweckmäßig unter Vorgabe des Tabellenadressenursprungs (Spalten- und Zeilennummer für die Funktion Cells). 9.5 2-fach verkettete lineare Listen Lineare Listen können als rekursive Datenstrukturen implementiert werden. Ein Listen-Objekt (hier VNode) enthält bei 2-facher Verkettung (als Attribute) einen Zeiger auf das vorhergehende (hier prv )und einen Zeiger auf das nachfolgende Listen-Objekt (hier nxt). Mit dieser Verkettung ist es bei vorgegebenem Listen-Objekt möglich, über die Verkettung einerseits bis zum ersten ListenObjekt zurück, andererseits zum letzten Listen-Objekt vorwärts zu laufen. Üblicherweise wird die verkettete Liste durch ein spezielles Objekt eröffnet bzw. abgeschlossen. Diese beiden Objekte können in einer Listen-Klasse als Attribute geführt werden Abbildung 39: (hier VListe), um sowohl über das erste als auch über das Objekte einer verketteten Liste letzte Listen-Objekt in eine Listen-Iteration einzusteigen. Ferner kann über diese Attribute ein neues Objekt sowohl als erstes als auch als letztes Objekt in die Liste eingefügt werden. Mit Ausnahme der Start- und Abschluss-Objekte der Liste können Listen-Objekten über einen Datenzeiger (hier dat) Datenobjekte referenzieren, d.h. sie zeigen auf die Instanzen (beliebiger Objekte), die in der Liste gespeichert werden sollen. Die zu implementierende Liste VListe erhält die folgenden für Listen üblichen Methoden.18 Methode Anmerkung AddF irst Fügt ein Objekt an erster Stelle in die Liste ein. AddLast Fügt ein Objekt an letzter Stelle in die Liste ein. GetF irst Liefert einen Zeiger auf das erste Listen-Objekt. GetN ext Liefert einen Zeiger auf das nächste Listen-Objekt. GetLast Liefert einen Zeiger auf das letzte Listen-Objekt. GetP rev Liefert einen Zeiger auf das vorhergehende Listen-Objekt. Insert Fügt ein Objekt in die Liste vor einem vorgegebenem ein. Remove Entfernt ein vorgegebenes Objekt aus der Liste. RemoveAll Entfernt alle Objekte aus der Liste. 18 Da es z.Z. in VBA nicht möglich ist einen Null-Zeiger abzufragen (nothing), erhält der VKnoten das Attribut Ken, das die folgenden Werte annehmen kann. Ken=0: Datenknoten, Ken=1: Startknoten und Ken=2: Endknoten. E. Baeck 9. VBA-OBJEKTE 9.5.1 Seite 47 Beispiel einer 2-fach verketten Liste In Abbildung 40 zeigt die Implementierung einer 2-fach verketteten Liste, die 3 Zeiger auf Instanzen des Klassenmoduls Stab enthält. Der 1. Knoten dient als Einstiegsknoten am Listenanfang (ken = 1 ), der letzte Knoten dient als Einstiegsknoten am Listenende (ken=2 ). Abbildung 40: Verkettete Liste mit 3 Stab-Instanzen Der Objektzeiger nxt enthält die Adresse des jeweils nächsten Knotens der Liste. Der Objektzeiger prv enthält die Adresse des jeweils vorhergehenden Knoten der Liste. Der Objektzeiger dat enthält für Datenknoten Zeiger auf die gespeicherten Datenobjekte (hier Stab-Instanzen). 9.5.2 Einfügen eines Datenknotens Das Einfügen eines Datenknotens in eine 2-fach verkettete Liste erfordert die Umordnung der Knotenzeiger in zwei Schritten. Zum einen sind die Knotenzeiger des neuen Knotens zu belegen. Zum andere sind die Knotenzeiger der bereits gespeicherten Knoten im Umfeld des Einfügens an D anzupassen. Abbildung 41 zeigt das Einfügen eines Knotens in eine 2-fach verkettete Liste. Die Liste enthält bereits die Knoten mit den Instanzen Stab1 und Stab3. Es soll die Instanz Stab2 zwischen die beiden genannen Instanzen eingefügt werden. In der Ausgangssituation sind Stab1 und Stab3 mit den blauen Pfeilen verAbbildung 41: Einfügen bzw. Entfernen eines Knotens kettet. Der nxt-Zeiger von Stab1 wird auf auf Stab2 gesetzt. In gleicher Weise wird der prv -Zeiger von Stab3 auf Stab2 gerichtet. Zusätzlich wird der nxt-Zeiger von Stab2 auf Stab3 und der prv -Zeiger von Stab2 auf Stab1 erzeugt. Nach Einfügen von Stab2 werden die Knoten im Umfeld von Stab2 durch die roten Pfeile verkettet. 9.5.3 Entfernen eines Datenknotens Das Entfernen eines Datenknotens aus einer 2-fach verkettete Liste erfordert die Umordnung der Knotenzeiger in zwei Schritten. Zum einen sind die Knotenzeiger des zu löschenden Knotens zu entfernen. Zum andere sind die Knoten vor und nach dem zu entfernenden Knoten mit einander zu verketten. Abbildung 41 zeigt das Löschen des Datenknotens von Stab2. Zunächst ist Stab2 noch eingebunden (blaue Pfeile). Es ist der nxt-Zeiger von Stab1 auf Stab3 zu setzen. Der prv -Zeiger von Stab3 ist auf Stab1 zu setzen. Beim Entfernen eines Knotens ist darauf zu achten, dass gelöscht wird, bevor die Zeiger auf ihn entfernt werden, da eine Instanz ohne Zeiger nicht mehr ansprechbar ist. 19.10.2011 Seite 48 9.5.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Iteratoren Der Iterator ist ein Zeiger mit dessen Hilfe eine Liste durchlaufen wird. Startpunkt einer Iteration ist bei einfach verketteten Listen der Kopf der Liste. Bei zweifach verketteten Listen kann zudem der das Ende der Liste als Startpunkt der Iteration gewählt werden. Die Iteration erfolgt in diesem Fall rückwärts über die Rückwärtsverkettung. Gängigerweise wird eine Iteration durch das Holen des Startzeigers initiiert. Darauf folgend wird in einer Schleife durch Holen des jeweils nächsten Zeigers die Iteration ausgeführt. Eine Listeniteration kann somit wie folgt im Pseudocode formuliert werden. • Hole 1. Zeiger (Kopfzeiger oder Endezeiger) • Hole nächsten Zeiger bis das Iterationsende erreicht ist. Der nächste Zeiger ist von der Iterationsrichtung abhängig. E. Baeck 10. REKURSIVE ALGORITHMEN 10 Seite 49 Rekursive Algorithmen Ein Algorithmus ist dann rekursiv, wenn er sich selbst enthält oder durch sich selbst teilweise definiert wird. Einer der bekanntesten und einfachsten rekursiven Algorithmen ist gegeben durch die Berechnung der Fakultät (siehe auch Abschnitt 5.1). n! = 1 (n − 1)! :n = 0 (27) : sonst Wie im Fall der Fakultät (27) bekannt, ist die rekursive Formulierung des Problems im Gegensatz zur direkten (2) nicht wirtschaftlich. 10.1 Quick-Sort Das Sortierverfahren QuickSort arbeitet nach der Devise Herrsche und Teile. Der Algorithmus geht zurück auf C.A.R Hoare 1960. Das zu sortierende Feld wird zerlegt in zwei Teilfelder. Die Teilung erfolgt durch Wahl eines beliebigen Elements P. Die Elemente der Teilfelder werden so umsortiert, dass im einen Teilfeild alle Elemente kleiner P im anderen Teilfeld alle Elemente größer P einsortiert werden. Die auf diese Weise generierten Teilfelder werden erneut in zwei Teilfelder durch Wahl eines jeweils neuen Teilerelements P zerlegt. Die Zerlegung eines Teilfeldes wird solange fort gesetzt, bis sich nur noch ein Element im Teilfeld befindet. Reduziert sich die Anzahl der Elemente alle Teilfelder auf ein Element, ist die Sortierung abgeschlossen. In Abbildung 42 wird das Wort SORTIERANGS alphabetisch sortiert. Das Abbildung 42: QuckSort: SORTIERANGST berandete Feld am rechten Intervallrand teilt das Intervall. Zum einen läuft ein Zeiger vom linken Intervallrand nach rechts und sucht das erste Zeichen, das größer oder gleich dem Teiler ist, dieses wird türkis eingefärbt. Andererseits läuft ein zweiter Zeiger von rechts nach links und sucht ein Zeichen, das kleiner oder gleich dem Teiler ist. Dieses Zeichen wird gelb 19.10.2011 Seite 50 Bauinformatik - Teil 1 - Übungsskript / 2011 dargestellt. Gelbes und türkises Zeichen werden getauscht. Daraufhin wird die Suche von beiden Seiten fortgesetzt. Gefundene Zeichen werden getauscht. Dies wird solange fort geführt, bis sich die beiden Zeiger treffen. Daraufhin wird das Zeichen, auf das der linksseitige Zeiger verweist mit dem Teilerzeichen getauscht. Das Teilerzeichen erhält damit seine endgültige Position. In Abbildung 42 werden gefundene Intervallgrenzen durch einen vertikalen roten Strich gekennzeichnet. Links- bzw. rechsseitiges Intervall (ohne das Teilerzeichen) werden erneut nach beschriebener Art umsortiert. Die Zerlegung in Teilintervalle wird solange fort gesetzt, bis die Teilintervallen nur noch ein Zeichen enthalten. Vertauschte Zeichen werden hellgrau gekennzeichnet. Zeichen, die bereits ihre endgültige Position erhalten haben, werden dunkelgrau gekennzeichnet. E. Baeck A. DREIMOMENTENGLEICHUNG, CLAPEYRON A Seite 51 Dreimomentengleichung, Clapeyron In diesem Abschnitt wird das Verfahren der Dreimomentengleichung oder Verfahren nach Clapeyron dargestellt (siehe auch [1]). A.1 Das Verfahren Mit der Dreimomentengleichung werden unter folgender Einschränkungen die Stützmomente mehrfeldriger Durchlaufträger berechnet. Abbildung 43: Durchlaufträger mit 8 Feldern Voraussetzungen: • Stützpunkte sind starr gelagert. • Auftretende Lasten wirken senkrecht zur Stabachse. • Die Biegesteifigkeit EI ist feldweise konstant. Für 2-feldrigen Abschnitt gilt (mit m ∈ [b, h] in Abbildung 43): Ml · ll + 2 · Mm · (ll + lr ) + Mr · lr = −Rl · ll − Lr · lr (28) mit: Ml , Mm , Mr , dem linken, mittleren und rechten Stützmoment ll , lr , der effektiven linken und rechten Feldweite Rl , Lr , dem linken und rechten Belastungsglied (rechte Seite) Die effektiven Feldweiten ll und lr sind bei unterschiedlichen Steifigkeiten auf ein Vergleichsträgheitsmoment Ic zu beziehen, d.h. ll = IIcl · ll,0 mit ll,0 , der realen Feldweite. A.2 Herleitung Vorgehen: Als statisch bestimmtes Grundsystem wird ein durch Gelenke entkoppelter Mehrfeldträger gewählt. Als statisch UnbeAbbildung 44: Statisch Unbestimmte an Zwischenlagern stimmte werden die Stützmomente in den Mittenlagern gewählt (Stützmomente an Randlagern verschwinden). Durch Ansetzen dieser Momente (als äußere Lasten) werden die Verdrehungen ϕ in den Gelenken in der Weise beeinflußt, dass sich in den Gelenken knicklose Übergänge (C1 stetig) ergeben. 19.10.2011 Seite 52 Bauinformatik - Teil 1 - Übungsskript / 2011 Für den in Abbildung 43 dargestellten Durchlaufträger ergeben sich für die Verdrehwinkel an den Lagern 1-7 bei Wahl der Stützmomente als statische Unbestimmte die folgenden Verträglichkeitsbedingungen (knickfreier Übergang zwischen den Feldern!). Aus den Verträglichkeits~ (X1 bis bedinungen folgt ein lineares Gleichungssystem für den gesuchten Momenten-Vektor X X7 ). Gl. X1 X2 X3 X4 X5 X6 X7 1 δ11 δ12 0 2 δ21 δ22 δ23 0 0 0 0 δ10 = 0 0 0 0 0 δ20 = 0 0 0 0 δ30 = 0 0 0 δ40 = 0 0 δ50 = 0 3 0 δ32 δ33 δ34 4 0 0 5 0 0 0 6 0 0 0 0 7 0 0 0 0 δ43 δ44 δ45 δ54 δ55 δ56 δ65 δ66 δ67 δ60 = 0 0 δ76 δ77 δ70 = 0 Tabelle 4: Gleichungssystem zur Ermittlung der Momente X1 bis X7 Da die Momentenfläche eines angesetzten 1Momente am Lager i jeweils dreieckförmig zu den benachbarten Lagern i − 1 und i + 1 ausläuft, ergeben sich bei der Integration der Eigenspannungszustände δij nur dann nicht verschwindende Werte wenn |i − j| ≤ 1. In Abbildung 45 werden die Momentenflächen für die ersten 5 Lager dargestellt. Es ist zu erkennen, dass jeweils zwei zur Mittelachse symmetrische Dreieckflächen benachbarter Lagerpunkte zu überlagern sind. Abbildung 45: Statisch Unbestimmte an Zwischenlagern δij = XZ 1 · Mi · Mj · dx = E·I s = δii = XZ s 1 · Mi2 · dx = E·I li , für i > j 6·E·I li+1 , für i < j 6·E·I li + li+1 , für Diagonalterme i = j 3·E·I (29) Aus Gleichung 29 und Tabelle 4 folgt: li li + li+1 li+1 + Xi · + Xi+1 · + δi0 = 0 6EI 3EI 6EI Xi−1 · li + 2 · Xi · (li + li+1 ) + Xi+1 · li+1 = −δi0 · 6 · E · I Xi−1 · E. Baeck (30) A. DREIMOMENTENGLEICHUNG, CLAPEYRON Seite 53 Die rechte Seite aus Gleichung 30 kann wie folgt umgeformt werden. δi0 = ϕi,r − ϕi,l 6 · E · I · ϕi,l = −Ri · li 6 · E · I · ϕi,r = Li+1 · li+1 (31) mit den Stabenddrehwinkeln19 ϕi,r und ϕi,l . Aus den Gleichungen 30 und 31 folgt die Formel von Clapeyron (siehe Gleichung 28). Es gibt spezielle Integrationstabellen (siehe z.B. [1] Seite 65) für die die Belastungsglieder Lr und Rl der Dreimomentengleichung (siehe Gleichung 28). Diese sind ebenso aus der allgemeinen Überlagerung der Belastungsmomentenfläche mit den jeweiligen Dreiecks.Momentenflächen des Einheitsmomentes am betrachteten Lagerpunkt zu erhalten. XXZ 1 δi0 = · (Mi + Mi+1 ) · M0,l · dx (32) E·I s l mit Mi , der linksseitigen, und Mi+1 , der rechtsseitigen Momentenfläche am Lager i. M0,l ist die Momentenfläche aus einer Belastung l. Bei der Berechnung von δi0 sind die Momentenflächen aller l Belastungen zu berücksichtigen. 19 Die Winkel ϕ sind Endwinkel eines Balkens auf zwei Stützen. Dies entspricht dem statisch bestimmten Grundsystems des Durchlaufträgers 19.10.2011 Seite 54 B Bauinformatik - Teil 1 - Übungsskript / 2011 Das ER-Modell Das ER-Modell (Entity-RelationshipModell) oder GegenstandsBeziehungs-Modell von Peter Pin-Shan Chen (1976) dient zur Beschreibung einer Datenstruktur in einem Modell bestehend aus graphischen Symbolen (siehe Abbildung 46). Eine ähnliche Visualisierung der Abhängigkeiten der Objekte des ER-Modells ist auch in der UML (Unified Modelling Language) zu finden. Abbildung 46: ER-Modell nach P.P. Chen • Entität (Entities): Objekt der Wirklichkeit, materiell oder abstrakt (zum Beispiel Lastfall oder Feld ). • Beziehung (Relationships): Semantische Beziehung zwischen zwei Objekten (zum Beispiel Lastfall enthält Lasten) • Attribut: Elementarinformation einer Entität oder einer Beziehung (z.B. hat eine Last eine Ordinate q, ein Feld hat eine Länge l). • Kardinalität: Mögliche Anzahl der an einer Beziehung beteiligten Entitäten (z.B. 1 Lastfall enthält 20 Lasten). Die Kardinalität wird optional am Ende einer Beziehungslinie angemerkt. E. Baeck C. UML-ASPEKTE C Seite 55 UML-Aspekte Die Unified Modeling Language ist eine überwiegend graphische Modellierungssprache für objektorientierte Entwicklungsansätze. Die UML geht zurück auf Booch, Rumbaugh und Jacobson. An dieser Stelle werden nur die Klassendiagramme erläutert, die als Erweiterung der ERDiagramme betrachtet werden können. Ein Klassendiagramm stellt die Beziehungen zwischen den einzelnen Klassen (Objekten) des Systems dar. Das Diagramm besteht aus Klassen, die durch Assoziation und/oder Generalisierung miteinander verbunden sind. Eine Klasse wird als Rechteck mit den 3 folgenden Bereichen dargestellt. • Der obere Bereich enthält den Namen der Klasse. • Der mittlere Bereich enthält die Liste der Attribute, d.h. die Daten, die eine Klasse umfaßt. • Der untere Bereich enthält die Methoden der Klasse (Klassen-Funktione). Assoziationen entsprechen den Relationen des ER-Modells. Sie werden durch Kanten dargestellt an deren Enden die Quantitäten vermerkt werden. Generalisierungen werden mit einer Richtung vorgegeben.20 Beispiel: Ein Beispiel objektorientierter Modellierung sind z.B. Geometrieobjekte eines CAD-Systems. Das Basis-Objekt der Modellierung ist das Geo-Objekt (Geometrieobjekt), es liefert die folgenden Standarddaten und Grundfunktionalität aller spezialisierten Objekte. Standarddaten Grundfunktionalität Abbildung 47: UML-Klassendiagramm : Farbe, Layer, Linientyp, Strickstärke. : Löschen, Verschieben, Rotieren, Spiegeln. Eine Generalisierung des Geo-Objektes wäre z.B. das Punkt-Objekt. Es geht aus dem GeoObjekt hervor und beerbt dessen Attribute und Funktionen. Zudem erhält das Objekt Punkt die Attribute x, y und z, die die Lage des Punktes im Raum beschreiben. Die Funktionen der Basisklasse Geo werden überschrieben mit speziellen Funktionen des Punktes. So ist im Gegensatz zur Linie beispielsweise beim Verschieben eines Punktes nur ein Ortsvektor zu variieren. 20 Generalisierungen wurden in VB nicht vorgesehen. In der aktuellen VB -Version wurde die Generalisierung implementiert. In VBA unter EXCEL wurde bislang auf Generalisierungen verzichtet. 19.10.2011 Seite 56 D Bauinformatik - Teil 1 - Übungsskript / 2011 Gauß’scher Algorithmus und Cholesky-Zerlegung In diesem Abschnitt wird der Gauß’sche Algorithmus zur Lösung des linearen Gleichungssystems erläutert. Bei den hier betrachteten Problemen ist das folgende symmetrisch-definites Gleichungssystem zu lösen2122 . A · x + b = 0 , mit AT = A und A positiv definit In Komponentendarstellung erhält man: a1,1 a1,2 . . . a1,n a2,1 a2,2 . . . a2,n .. .. · .. .. . . . . an,1 an,2 . . . an,n x1 (33) b 1 x2 b2 = ... ... xn bn (34) oder n X aik · xk + bi = 0 (i = 1, 2, ..., n) (35) k=1 Zur Lösung der Dreimomentengleichungen (Clapeyron) wären die Einträge der Matrix A die Längengewichte der Momente. Der Vektor x wäre der Vektor der gesuchten Stützmomente, der Vektor b, der Vektor der Belastungsglieder. D.1 Der Gauß’sche Algorithmus In einem ersten Schritt eliminiert man die erste Unbekannte x1 aus den Gleichungen 2 bis n, in dem das (ai1 /a11 )-fache der ersten Zeile von der i-ten Zeile subtrahiert wird. Damit erhält man ein reduziertes Gleichungssystem für die Unbekannten x2 bis xn . n X (1) (1) aik · xk + bi =0 (i = 2, 3, ..., n) (36) (i, k = 2, 3, ..., n) (37) (i = 2, 3, ..., n) (38) k=2 mit (1) aik (1) bi ai1 · a1k a11 ai1 · b1 = bi − a11 = aik − es werden die folgenden l-Faktoren eingeführt li1 = ai1 a11 (i = 2, 3, ..., n) (39) Unter Berücksichtigung von (39) folgt aus (37) und (38)23 (1) 21 aik = aik − li1 · ak1 (1) bi = bi − li1 · b1 (40) (i = 2, 3, ..., n; k = 2, 3, ..., i) (41) Weiterführende Erläuterungen und Algorithmen siehe [2]. Für eine transponierte Matrix AT gilt: ATi,j = Aj,i . 23 Die li1 können erst nach Abschluss des Reduktionsschrittes in den Speicher der ai1 geschrieben werden. 22 E. Baeck D. GAUß’SCHER ALGORITHMUS UND CHOLESKY-ZERLEGUNG Seite 57 In (40) und (41) wurde die Symmetrie der Matrix A berücksichtigt. Zum einen läuft der Index k nicht mehr bis n, sondern nur noch bis i, d.h. bis zur Diagonalen der Matrix. Zum zweiten wurde in (40) a1k durch ak1 ersetzt. Damit kann auf die Matrixeinträge des oberen Dreiecks verzichtet werden. Wird die erste Gleichung aus (35) durch a11 dividiert, so folgt mit (39) die Bestimmungsgleichung für die Unbekannte x1 .24 x1 = − n X lk1 · xk − c1 mit c1 = k=2 b1 a11 (42) Mit dem reduzierten Gleichungssystem der Stufe (1) (Bestimmungsgleichungen für x2 bis xn (36)), folgen in analoger Weise die Größen des reduzierten Gleichungssystems der Stufe (2). Die l-Faktoren ergeben sich zu (1) li2 = ai2 (i = 3, 4, ..., n) (1) (43) a22 die Koeffizienten der zweiten Stufe ergeben sich zu (2) aik (2) bi (1) (1) = aik − li2 · ak2 (1) bi = (44) − li2 · b2 (i = 2, 3, ..., n; k = 2, 3, ..., i) (45) und die Bestimmungsgleichung für die Unbekannte x2 ergibt sich zu x2 = − n X (1) lk2 · xk − c2 mit c2 = k=3 b2 (1) (46) a22 Bei konsequenter Fortführung dieser Reduktion folgt nach n − 1 Schritten die Bestimmungsgleichung der letzten Unbekannten xn zu a(n−1) · xn + b(n−1) =0 nn n (47) und somit folgt für die letzte Unbekannte xn (n−1) xn = −cn mit cn = bn (n−1) (48) ann Die Berechnung aller Unbekannten x1 bis xn erfolgt somit rekursiv, d.h. zur Berechnung der 1. Unbekannten ist die Lösung der 2. erforderlich, zur Berechnung der 2. die 3. usw.. Nach vollständiger Reduktion des Gleichungssystems (35) zu (48), können sozusagen rückwärts, deshalb Rückwärtseinsetzen, alle Unbekannten xn−1 , xn−2 bis x1 ermittelt werden. 24 Die ci Werte werden in den Speicher der bi -Werte geschrieben. 19.10.2011 Seite 58 D.2 Bauinformatik - Teil 1 - Übungsskript / 2011 Interpretation des Gauß’schen Algorithmuses als Dreieckszerlegung Aus den Gleichungen des Abschnitts D.1 folgen die Lösung des linearen Gleichungssystems für eine Inhomogenität oder rechte Seite, d.h. einen Vektor b. Da i.A. mehrere Lastfälle zur Berechnung vorliegen, müßte nach dem besprochenen Algorithmus für jeden Lastfall individuell eine Lösung berechnet werden. Mit der Interpretation des Gauß’schen Algorithmuses als Zerlegung einer Matrix A in eine Linksdreiecksmatrix L mit 1-Werten auf der Diagonalen und eine Rechtsdreiecksmatrix R läßt sich eine Berechnungsvorschrift ableiten, die den Lösungsalgorithmus in drei Schritte aufspaltet, wobei der aufwendigste erste Schritt unabhängig von der rechten Seite, d.h. unabhängig vom Lastvektor durchgeführt werden kann. 1 0 0 l21 1 0 l31 l32 1 l41 l42 l43 a a12 a13 a14 11 (1) (1) (1) 0 0 a22 a23 a24 · (2) (2) 0 a33 a34 0 0 (3) 1 0 0 0 a44 0 a 11 a = 21 a31 a41 a12 a13 a14 a22 a23 a24 (49) a32 a33 a34 a42 a43 a44 L·R = A Die Beziehung (49)25 läßt sich elementar z.B. durch (44) im Fall des ersten reduzierten Gleichungssystems zeigen. Die Rechtsdreiecksmatrix R läßt sich auf die Linksdreiecksmatrix L in folgender Beziehung zurück führen. a11 a12 a13 a14 (1) 0 a(1) a23 22 R = (2) 0 0 a33 0 0 0 a 0 0 11 (1) 0 a22 0 = (2) 0 0 a33 0 0 0 (1) a24 (2) a34 (3) a44 0 1 l21 l31 l41 0 0 1 l32 l42 · 0 0 0 1 l43 (3) a44 0 0 0 1 (50) = D · LT Aus (49) und (50) folgt die Gleichung der Dreieckszerlegung nach Gauß. A = L · D · LT (51) Damit folgt für das lineare Gleichungssystem (34) L · D · LT x + b = 0 25 (52) Zur Erläuterung der matriziellen Zusammenhänge wird der Fall n = 4 in Komponentenform dargestellt. Die Verallgemeinerung auf beliebige Dimension erfolgt entsprechend. E. Baeck D. GAUß’SCHER ALGORITHMUS UND CHOLESKY-ZERLEGUNG Seite 59 Zur Bestimmung der Unbekannten wird zunächst der Hilfsvektor y wie folgt eingeführt26 . y = −D · LT · x (53) Der Vektor y wird zudem wie folgt in c skaliert. D·c=y (54) Somit kann (52) in den folgenden 3 Schritten umformuliert werden. −L·y+b = 0 (55) −D · c + y = 0 (56) LT · x + c = 0 (57) Die Unbekannten xi für mehrere Lastfälle wird demnach in den folgenden 3 Schritten ermittelt. • Dreieckszerlegung Die Matrix A wird nach (51) unabhängig von den rechten Seiten in eine Lingsdreiecksmatrix und eine Diagonalmatrix zerlegt. • Vorwärtseinsetzen Berechnung einer modifizierten rechten Seite c nach (55 und 56). • Rückwärtseinsetzen Berechnung aller Unbekannten mit modifizierten rechten Seite c nach (57). Der Vorteil dieses Verfahrens ist, dass der aufwendigste Schritt, die Dreieckszerlegung der Koeffizientenmatrix (O(n3 )), nur einmal für alle Lastfälle (Inhomogenitäten b) durchzuführen ist. Die Berechnung der Unbekannten durch Vorwärtseinsetzen (O(n2 )) und Rückwärtseinsetzen (O(n2 )) erfolgt dann für jeden Lastfall individuell. 26 Bei Anwendung der Standardvariante des Gauß’schen Algorithmus wird das Gleichungssystem für jede rechte Seite (Lastfall) individuell gelöst. Ziel der Betrachtung hier ist, den aufwendigen Schritt der Zerlegung im Falle mehrerer rechter Seiten, d.h. für mehrere Lastfälle, von der Berechnung der Unbekannten zu separieren, sodass die Zerlegung nur einmal durchgeführt werden muss. 19.10.2011 Seite 60 D.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Die Cholesky-Zerlegung Zur optimalen Nutzung des Speichers werden die Faktoren lik an die Stelle der entsprechenden Matrixelemente der Matrix A gespeichert. Der Gauß’sche Algorithmus wirft das Problem auf, dass die Faktoren lik erst dann auf die Matrixelemente abgespeichert werden können, wenn der Eliminationsschritt vollständig durchgeführt wurde (siehe Gleichung 44). Wird darauf nicht geachtet, gehen Matrixelemente verloren, die zukünftig noch gebraucht werden. Durch Cholesky’s Idee einer symmetrischen Zerlegung der Matrix A wird dieses Problem gelöst. Der Algorithmus wird vereinfacht. Durch die symmetrische Aufspaltung der Matrix A wird aus den Diagonalelementen die Wurzel gezogen. Dies reduziert die Größenordung der Matrixelemente √ √ auf die Halfte (z.B. 100 = 10 und 10000 = 100), die Matrixelemente rücken zusammen, was zu einer besseren Konditionierung der Matrix und dadurch zu einer höheren numerische Stabilität der Berechnung führt. Die Zerlegung nach Cholesky ergibt folgende Beziehung. A = L · LT (58) Die Diagonalelemente der Gauß’schen Zerlegung, Matrix D (51) werden in der CholeskyZerlegung symmetrisch in die Dreiecksmatrizen L und LT aufgenommen. Damit ergibt sich die folgende Beziehung. A=L Chol · LTChol , mit L Chol =L Gaus · D(1/2) (59) Für die l-Faktoren ergibt sich mit ai1 li1 = √ a11 (i = 2, 3, ..., n) (60) (i = 2, 3, ..., n; k = 2, 3, ..., i) (61) die symmetrische Form27 (1) aik = aik − li1 · lk1 wobei für die erste Gleichung gilt l11 = c1 = √ a11 , und c1 b1 = √ a11 l11 (62) Mit (60), (61) und (62) folgt für die Bestimmungsgleichung für die erste Unbekannte x1 " n # X 1 x1 = − · lk1 · xk + c1 l11 (63) k=2 für (45) folgt mit (60) und (62) (1) bi 27 = bi − li1 · c1 (i = 2, 3, ..., n) (64) Aus (61) folgt, dass unmittelbar nach Berechnung eines neuen Matrixelements, das entsprechend alte nicht mehr benötigt wird, d.h. das neue kann unmittelbar nach Berechnung auf den Speicherplatz des alten geschrieben werden. E. Baeck D. GAUß’SCHER ALGORITHMUS UND CHOLESKY-ZERLEGUNG Seite 61 Das Aufstellen der reduzierten Gleichungssysteme erfolgt analog zur Gauß’schen Zerlegung. Für das reduzierte Gleichungssystem der zweiten Stufe ergibt sich folgende Gleichungen. l22 (2) aik c2 (2) bi q (1) = a22 (1) , li2 = (1) = aik − li2 · lk2 b2 = l22 (1) = bi − li2 · c2 ai2 l22 (i = 3, 4, ..., n) (i = 3, 4, ..., n; k = 3, 4, ..., i) (65) (66) (67) (i = 3, 4, ..., n) (68) Die Gleichungen (65) und (66) zeigen die symmetrische Zerlegung nach Cholesky, die Gleichungen (67) und (68) das Vorwärtseinsetzen, die Berechnung des Hilfsvektors zur Ermittlung der Unbekannten im Rückwärtseinsetzen. Die Linksdreiecksmatrix nach der Cholesky-Zerlegung (vgl. (58)) hat die folgende Gestalt. l11 0 0 0 l21 l22 0 0 (69) L= l31 l32 l33 0 l41 l42 l43 l44 Im Gegensatz zum Gauß’schen Algorithmus benötigt der Algorithmus nach Cholesky nur einen Hilfvektor (c = −LT · x) für das Vorwärts-, Rückwärtseinsetzen. Die Skalierung mit der Diagonalmatrix (siehe (56)) entfällt. Für das lineare Gleichungssystem (33) folgt mit der Zerlegung (58) L · LT · x + b = 0 (70) Der Hilfsvektor der Lastseite c wird durch das Vorwärtseinsetzen (71) berechnet. Die Unbekannten ergeben sich aus dem Rückwärtseinsetzen (72)mit Hilfe des Vektors c. −L·c+b = 0 (71) LT · x + c = 0 (72) 19.10.2011 Seite 62 D.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Pseudocode für Cholesky-Zerlegung Die Berechnung der Unbekannten aus dem linearen Gleichungssystem (33) werden für mehrere rechte Seiten, d.h. Lastfälle, sinnvollerweise durch drei getrennte Programmteile (Funktionen) implementiert, • die Dreieckszerlegung, • das Vorwärtseinsetzen und • das Rückwärtseinsetzen, wobei die Dreieckszerlegung nur einmal, das Vorwärts- und Rückwärtseinsetzen für jede rechte Seite b, d.h. für jeden Lastfall erfolgt. D.4.1 Pseudocode der Zerlegung Der Prozess der Dreieckszerlegung wird durch den folgenden Pseudocode beschrieben. für p = 1, 2, ..., n √ lpp = app für i = p + 1, p + 2, ..., n lip = aip /lpp für k = p + 1, p + 2, ..., i für aik = aik − lip · lkp (58’) D.4.2 Pseudocode des Vorwärtseinsetzens Der Prozess des Vorwärtseinsetzens wird durch den folgenden Pseudocode beschrieben. für k = 1, 2, ..., n s = bk für i = 1, 2, ..., k − 1 s = s − lki · ci ck = s/lkk (71’) D.4.3 Pseudocode des Rückwärtseinsetzens Der Prozess des Rückwärtseinsetzens wird durch den folgenden Pseudocode beschrieben. für k = n, n − 1, ..., 1 s = ck für i = k + 1, k + 2, ..., n s = s + lik · xi xk = −s/lkk (72’) E. Baeck D. GAUß’SCHER ALGORITHMUS UND CHOLESKY-ZERLEGUNG D.5 Seite 63 VBA-Code des Gleichungslösers nach Cholesky In diesem Abschnitt werden die VBA-Codes für die Dreieckszerlegung nach Cholesky sowie die Codes des Vorwärts- und Rückwärtseinsetzens gegeben. Der VBA-Code ergibt sich aus der direkten Umsetzung des Pseudocodes (siehe Abschnitt D.4) in die VBA-Sprache. D.5.1 VBA-Code der Cholesky-Zerlegung Option Explicit ’ Zerlegen einer Matrix A(n x n) nach Cholesky ’ ’ A = L * L^T ’ ’ A: Dim A(1 to n, 1 to n) Public Function Cholesky(n As Integer, a() As Double) As Integer Dim P As Integer Dim i As Integer Dim k As Integer ’ über die Spalten For P = 1 To n ’ Matrix nicht zerlegbar If a(P, P) <= 0 Then Cholesky = 1 Exit Function End If a(P, P) = Sqr(a(P, P)) ’ über die Zeilen For i = P + 1 To n a(i, P) = a(i, P) / a(P, P) ’ Zeilensubtraktion For k = P + 1 To i a(i, k) = a(i, k) - a(i, P) * a(k, P) Next Next Next Cholesky = 0 End Function 19.10.2011 Seite 64 D.5.2 Bauinformatik - Teil 1 - Übungsskript / 2011 VBA-Code des Vorwärtseinsetzens ’ Vorwärtseinsetzen Public Sub Vorwaerts(n As Integer, L() As Double, b() As Double, c() As Double) Dim k As Integer Dim i As Integer Dim s As Double For k = 1 To n s = b(k) For i = 1 To k - 1 s = s - L(k, i) * c(i) Next c(k) = s / L(k, k) Next End Sub D.5.3 VBA-Code des Rückwärtseinsetzens ’ Rückwärtseinsetzen Public Sub Rueckwaerts(n As Integer, L() As Double, c() As Double, x() As Double) Dim k As Integer Dim i As Integer Dim s As Double For k = s = ’ s = For n To 1 Step -1 -c(k) ’ "-" falls: A*x = b +c(k) ’ "+" falls: A*x + b = 0 i = k + 1 To n s = s + L(i, k) * x(i) Next x(k) = -s / L(k, k) Next End Sub E. Baeck E. LÖSUNGEN ZUM ABSCHNITT ELEMENTARE ALGORITHMEN E Seite 65 Lösungen zum Abschnitt Elementare Algorithmen In diesem Anhang werden Lösungsvorschläge zu den Aufgaben im Abschnitt 5 gegeben. Auf die Darstellung an die Eventfunktionen wird hierbei verzichtet, da diese bei allen Programmen ähnlich ist und damit aus der Darstellung des Abschnitts 4.1 prinzipiell entnommen werden kann. E.1 Summe aller Zahlen aus vorgegebenem Intervall ’ Summe der ganzen Zahlen von "VON" nach "BIS" Public Sub Summe() ’ Deklaration Dim von As Integer Dim bis As Integer Dim sum As Integer Dim i As Integer Abbildung 48: Eingabefelder und Programstart ’ Initialisierung sum = 0 ’ Hole Daten aus Tabelle von = Range("VON") bis = Range("BIS") ’ Berechnung der Summe For i = von To bis sum = sum + i Next ’ Schreibe Ergebnis in Tabelle Range("SUM") = sum End Sub 19.10.2011 Seite 66 E.2 Bauinformatik - Teil 1 - Übungsskript / 2011 Berechnung der Fakultät Aufgabenstellung in Abschnitt 5.1. ’ Berechnung der Fakultät Public Sub Fakultaet() Dim n As Integer Dim i As Integer Dim f As Double ’ Eingangsgröße ’ Laufvariable ’ Ergebnis: Achtung 8Bytes! erforderlich ’ Initialisierung f = 1 n = Range("NWERT") Abbildung 49: Eingabefelder und Programstart ’ Berechnung For i = 2 To n f = f * i Next ’ Ergebnis Range("NFAKULTAET") = f End Sub E. Baeck E. LÖSUNGEN ZUM ABSCHNITT ELEMENTARE ALGORITHMEN E.3 Seite 67 Berechnung des Binomialkoeffizienten Aufgabenstellung in Abschnitt 5.228 ’ Berechnung des Binomialkoeffizienten Public Sub Binomi() Dim i As Integer Dim f As Double ’ Ergebnis kritsch! => 8Bytes! Dim n As Integer Dim m As Integer ’ Eingangsgrößen aus Tabelle n = Range("B_N") m = Range("B_M") Abbildung 50: Eingabefelder und Programstart f = 1 ’ Berechnung For i = 1 To m f = f * (n - i + 1) / i Next ’ Ausgabe in Tabelle Range("W_BIN") = f End Sub 28 Das Beispiel zeigt die möglichen Kombinationen für die Auswahl von 6 aus 49. Der Kehrwert wäre die Wahrscheinlichkeit einen 6er im Lotto zu holen. Füllen Sie also 14 Millionen Lottoscheine aus und es wird Ihnen einmal das große Glück zu winken. Dies allerdings nur, bei hinreichend häufiger Wiederholung! 19.10.2011 Seite 68 E.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Beispiel 4: Winkel zwischen 2 Vektoren im Rn Aufgabenstellung in Abschnitt 5.3 VBA liefert keine Arkuskosinus-Funktion. Arkuskosinus wird wie folgt auf Arkustangens zurück geführt29 . −x arccos(x) = arctan √ +π (73) 1 − x2 ’ Berechnung des Winkels zwischen 2 Vektoren aus R^n Public Function Winkel(i0 As Integer, j0 As Integer) Dim i As Integer Dim dm As Integer ’ Laufindex ’ Dimension Dim Dim Dim Dim Dim Dim ’ ’ ’ ’ ’ ’ V1() As Double V2() As Double L1 As Double L2 As Double L3 As Double cs As Double Vektor 1 Vektor 2 Vektorlänge 1 Vektorlänge 2 Skalarpodukt V1, V2 Cosinus-Wert i = 1 ’ Dimension ermitteln Do While (Cells(i + i0, 1 + j0) <> "") i = i + 1 Loop dm = i - 1 ’ Dimensionierung der Vektoren ReDim V1(1 To dm) ReDim V2(1 To dm) ’ Einlesen der Vektoren For i = 1 To dm V1(i) = Cells(i + i0, 1 + j0) V2(i) = Cells(i + i0, 2 + j0) Next Abbildung 51: Eingabefelder und Programstart ’ Vektorlängen berechnen L1 = Sqr(SkalProd(V1, V1)) L2 = Sqr(SkalProd(V2, V2)) L3 = SkalProd(V1, V2) 29 Die Umrechnung von Rad in Grad erfolgt durch Skalierung mit Faktor E. Baeck 45 arctan(1) E. LÖSUNGEN ZUM ABSCHNITT ELEMENTARE ALGORITHMEN Seite 69 ’ Winkelberechnung cs = L3 / (L1 * L2) ’ Berechnung des Winkels in Grad Winkel = acos(cs) * 45# / Atn(1#) End Function ’ arccos - Arcuscosinus Function acos(x) acos = Atn(-x / Sqr(-x * x + 1)) + 2 * Atn(1) End Function ’ Berechnung des Skalarprodukts Function SkalProd(a() As Double, b() As Double) Dim nu As Integer Dim no As Integer Dim s As Double nu = LBound(a) no = UBound(b) s = 0 ’ untere Grenze ’ obere Grenze ’ über alle For i = nu To no s = s + a(i) * b(i) Next SkalProd = s End Function 19.10.2011 Seite 70 E.5 Bauinformatik - Teil 1 - Übungsskript / 2011 Lösung der sinus-Entwicklung Das Programm wird als Eventfunktion zum Click -Ereignis der Schaltfläche in der Tabelle implementiert. Private Sub SinusStart_Click() Dim Dim Dim Dim f As Double x As Double eps As Double t As Double Dim i As Long Dim j As Long Dim g As Integer On Error GoTo Fehler g = 0 ’ Löschen der Ausgabebereiche Range("sinus_kom") = "" ’ Löschen der Tabelle i = 10 Do While Cells(i, 2) <> "" Cells(i, 2) = "" Cells(i, 3) = "" Cells(i, 4) = "" i = i + 1 Loop ’ Eingabedaten x = Range("sinus_x") eps = Range("sinus_eps") ’ Initialisierung f = 0: g = 1 x = x * Atn(1) / 45 ’ Term 1 f = x: t = x i = 1: j = 1 Cells(9 + i, 2) = i Cells(9 + i, 3) = t Cells(9 + i, 4) = f E. Baeck E. LÖSUNGEN ZUM ABSCHNITT ELEMENTARE ALGORITHMEN Seite 71 ´ ’ Summationsschleife Do While Abs(t) > eps t j t j t f = = = = = = -t * x * x j + 1 t / j j + 1 t / j f + t ’ Ausgabe i = i + 1 Cells(9 + Cells(9 + Cells(9 + in die Tabelle i, 2) = i i, 3) = t i, 4) = f Loop g = 2 Exit Sub Fehler: Range("sinus_kom") = "Programmfehler: Überlauf (Code " & g & ")!" End Sub 19.10.2011 Seite 72 E.6 Bauinformatik - Teil 1 - Übungsskript / 2011 Implementierung des Newton-Verfahrens Das Verfahren besteht aus drei Programmteilen, dem Unterprogramm newton und den Funktionen f bzw. fs. In vorliegender Implementierung wird die Ableitung der Funktion numerisch berechnet. Da es in VBA nicht möglich ist, als Parameter eine Funktion zu übergeben, erhält die Funktion generell die Bezeichnung f. Die Funktion f ist demzufolge ebenfalls als Programmeingabe zu verstehen. Option Explicit ’ alle Variablen deklarieren ’ Funktion Private Function f(x As Double) As Double f = x ^ 2 - 1 End Function ’ Numerische Ableitung der Funktion f(x) Private Function fs(x As Double) As Double Dim h As Double h = 0.00001 fs = (f(x + h / 2) - f(x - h / 2)) / h End Function ’ Newtonalgorithmus Public Sub newton() Dim Dim Dim Dim x As Double eps As Double nx As Integer n As Integer Dim z0 As Integer Dim s0 As Integer ’ Ursprung der Ausgabetabelle ’ Initialisierung x = Range("NX0") eps = Range("NEPS") nx = Range("NIX") n = 0 z0 = 13 s0 = 1 ’ Zurücksetzen der Ausgabetabelle ’ ... noch ein Geheimnis ... ’ Iterationsschleife Do ’ Fall 1: Nullstelle gefunden If Abs(f(x)) < eps Then E. Baeck E. LÖSUNGEN ZUM ABSCHNITT ELEMENTARE ALGORITHMEN Seite 73 Range("NXN") = x Range("NIT") = n Range("NKOM") = "Nullstelle gefunden!" Exit Sub ’ Fall 2: Anzahl zulässiger Iterationen erreicht ElseIf n >= nx Then Range("NXN") = "---" Range("NIT") = n Range("NKOM") = "Keine Nullstelle gefunden!" Exit Sub ’ Fall 3: Horizontale Tangente ElseIf Abs(fs(x)) < eps Then Range("NXN") = "---" Range("NIT") = n Range("NKOM") = "Abbruch wegen horizontaler Tangente!" Exit Sub End If ’ Iterationsschritt x = x - f(x) / fs(x) n = n + 1 ’ Protokoll der Iteration Cells(z0 + n, s0 + 1) = n Cells(z0 + n, s0 + 2) = x Cells(z0 + n, s0 + 3) = f(x) Cells(z0 + n, s0 + 4) = fs(x) Loop End Sub 19.10.2011 Seite 74 F Bauinformatik - Teil 1 - Übungsskript / 2011 Lösungen zum Clapeyron-Problem In diesem Abschnitt werden Lösungsvorschläge für das Clapeyron-Problem zusammen gestellt. F.1 Aufgabe 8.3.1 Eine mögliche Datenstrukturen gemäß der ER-Modelle wäre die folgende. ’ Daten eines Feldes Type Feld L As Double i As Double End Type ’ Feldlänge ’ Trägheitsverhältnis Der Container für die Felder wird als globale Variabel angelegt, d.h. er ist aus allen Routinen des Moduls direkt ansprechbar. Zudem wird die Anzahl der Felddaten nFeld als globale Variabel geführt. ’ Globale Variable Dim FA() As Feld ’ Container für die Felder Dim nFeld As Integer ’ Feldanzahl E. Baeck F. LÖSUNGEN ZUM CLAPEYRON-PROBLEM F.2 Seite 75 Aufgabe 8.3.2 Eine mögliche Datenstrukturen gemäß der ER-Modelle wären die folgende. ’ Daten einer Streckenlast Type SLast nF As Integer q As Double a As Double c As Double End Type ’ Daten einer Punktlast Type PLast nF As Integer P As Double a As Double End Type ’ Daten einer Punktmoment Type PMoment nF As Integer M As Double a As Double End Type ’ Daten eines Lastfalls Type Lastfall Nr As Integer ’ Lasten und Momente SL() As SLast PL() As PLast PM() As PMoment End Type ’ ’ ’ ’ Feldnummer Ordinate Position im Feld Einleitungslänge ’ Feldnummer ’ Ordinate ’ Position im Feld ’ Feldnummer ’ Ordinate ’ Position im Feld ’ Lastfallnummer ’ Container der Streckenlasten ’ Container der Punktlasten ’ Container der Punktmomente ’ Index für Lastfall ’ "Strichliste" zum Zählen der Lasten Type IndLF Nr As Integer ’ Lastfallnummer SL As Integer ’ Zähler der Streckenlasten PL As Integer ’ Zähler der Punktlasten PM As Integer ’ Zähler der Punktmomente End Type 19.10.2011 Seite 76 F.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Einlesen der Systemdaten und Aufbau des Datenmodell Das Programm zählt in einem ersten Schritt die Anzahl der eingegeben Felder, legt dann den Container in entsprechender Größe an und überträgt dann in einem zweiten Schritt die Daten aus der Tabelle in das Datenmodell. ’ Einlesen der Strukturdaten ’ Tabellenoffset: i0, j0 ’ Rückgabe: Fehlerkenner = 0 (alles ok) Public Function LeseSystem(i0 As Integer, j0 As Integer) As Integer ’ Schritt 1: Feldanzahl ermitteln Dim i As Integer ’ Laufindex der Zeilen Dim j As Integer ’ Laufindex der Spalten ’ Initialisierung LeseSystem = 0 nFeld = 0 i = i0 + 1 j = j0 + 1 ’ ’ ’ ’ 0: alles ok Initialisierung der Feldanzahl 1. Zeile 1. Spalte ’ über alle Zeilen bis leeres Feld gefunden Do While (Cells(i, j) <> "") i = i + 1 Loop ’ Anzahl der Felder: Offset und Leerfeld berücksichtigen nFeld = i - i0 - 1 ’ Wurden Felder eingegeben? If nFeld < 1 Then LeseSystem = 1 Exit Function End If ’ Container anlegen ReDim FA(1 To nFeld) ’ Schritt 2: Daten lesen und speichern For i = 1 To nFeld FA(i).L = Cells(i + i0, 1 + j0) FA(i).i = Cells(i + i0, 2 + j0) Next End Function E. Baeck F. LÖSUNGEN ZUM CLAPEYRON-PROBLEM F.4 Seite 77 Einlesen der Belastungsdaten und Aufbau des Datenmodell Das Problem des Aufbaus der Belastungsdaten wird in zwei verschiedene Unterprogramme separiert.30 • Der Aufbau des Lastfall-Indexvektors. • Der Aufbau des Lastfall-Containers. F.4.1 Aufbau des Lastfall-Indexvektors Der Lastfallindex-Vektor ILF wird wie der Feld-Container als globale Variable deklariert. Zudem werden die Anzahl der Lastdaten nLast und die extremalen Lastfallnummern lfmin und lfmax als globale Variabel geführt. ’ Globale Variable Dim ILF() As IndLF ’ Container der Lastindizes Dim nLast As Integer Dim lfmin As Integer Dim lfmax As Integer ’ Lastdatenanzahl ’ minimale Lastfallnummer ’ maximale Lastfallnummer In einem ersten Schritt wird der Lastfallnummern-Bereich ermittelt.3132 ’ Aufbau des Lastfall-Indexvektors ’ Tabellenoffset: i0, j0 ’ Rückgabe: Fehlerkenner = 0 (alles ok) Public Function GenLastIndex(i0 As Integer, j0 As Integer) As Integer ’ Schritt 1: Lastfallbereich ermitteln Dim i As Integer ’ Laufindex der Zeilen Dim lf As Integer ’ Lastfallnummer aus Tabelle Dim typ As Integer ’ Lastfalltyp aus Tabelle ’ Initialisierung GenLastIndex = 0 nLast = 0 i = 1 ’ 1. Zeile ’ über alle Zeile Do While (Cells(i + i0, 1 + j0) <> "") lf = Cells(i + i0, 1 + j0) ’ Lastfallnummer lesen 30 Das Zerlegen längerer Programmsequenzen in abgegrenzte Einheiten, Module führt i.A. zu wesentlich übersichtlicheren und dadurch verständlicheren Programmen. Daumenwert für die maximale Code-Länge sind 1-2 A4-Seiten im Ausdruck. 31 Bei der select case Anweisung im Schritt 2, die in verschiedene Lasttypen verzweigt, wurden in den caseZweigen jeweils zwei Code-Zeilen mit dem : aus Gründen der Übersichtlichkeit zusammen gefasst. 32 Wenn in einer if...endif -Klammer nur eine Anweisung ausgeführt werden soll, kann auf die Schlüsselworte then und endif verzichtet werden. 19.10.2011 Seite 78 Bauinformatik - Teil 1 - Übungsskript / 2011 ’ 1. Datensatz => Initialisierung If i = 1 Then lfmax = lf lfmin = lf ’ Extremale Lastfallnummern herausfischen Else If lfmax < lf Then lfmax = lf If lfmin > lf Then lfmin = lf End If i = i + 1 Loop ’ Anzahl der Lasten nLast = i - 1 ’ Wurden Lasten eingegeben? If nLast < 1 Then GenLastIndex = 1 Exit Function End If ’ Container anlegen ReDim ILF(lfmin To lfmax) ’ Schritt 2: Lastdaten der Lastfälle zählen For i = 1 To nLast lf = Cells(i + i0, 1 + j0) ’ Lastfallnummer ILF(lf).Nr = lf ’ ... übernehmen typ = Cells(i + i0, 3 + j0) ’ Lasttyp ’ Welche Last liegt vor Select Case typ ’ Steckenlast zählen Case 1: ILF(lf).SL = ILF(lf).SL + 1 ’ Punktlast zählen Case 2: ILF(lf).PL = ILF(lf).PL + 1 ’ Punktmoment zählen Case 3: ILF(lf).PM = ILF(lf).PM + 1 End Select Next End Function E. Baeck F. LÖSUNGEN ZUM CLAPEYRON-PROBLEM F.4.2 Seite 79 Aufbau des Lastfall-Containers Der Lastfall-Container LA wird wie der Feld-Container als globale Variable deklariert. ’ Globale Variable Dim LA() As Lastfall ’ Container der Lastfälle In einem ersten Schritt wird der Lastfall-Container aus der Information des Lastfall-Indexvektors dimensioniert. Bevor die Lasten in die Container eingelesen werden, werden die Lastenzähler im Lastfall-Indexvektor zurück gesetzt (=0). Da als Container indizierte Variablen (Felder) eingesetzt werden, benötigt man einen Füllzeiger, der als Index für den jeweils nächsten Datensatz eingesetzt wird. ’ Aufbau des Lastfall-Containers und einlesen der Lastdaten ’ Tabellenoffset: i0, j0 ’ Rückgabe: Fehlerkenner = 0 (alles ok) Public Function GenLastdaten(i0 As Integer, j0 As Integer) As Integer ’ Schritt 1: Dimensionierung des Lastfall-Containers Dim i As Integer ’ Laufindex der Zeilen Dim lf As Integer ’ Lastfallnummer aus Tabelle Dim typ As Integer ’ Lastfalltyp aus Tabelle ’ Initialisierung GenLastdaten = 0 ’ Dimensionieren der Lastfälle ReDim LA(LBound(ILF) To UBound(ILF)) ’ über alle Lastfälle For i = LBound(ILF) To UBound(ILF) ’ für vorhandene Lastfälle werden die ’ Last-Container dimensioniert If ILF(i).Nr > 0 Then ’ Streckenlasten dimensionieren If ILF(i).SL > 0 Then ReDim LA(i).SL(1 To ILF(i).SL) ’ Punktlasten dimensionieren If ILF(i).PL > 0 Then ReDim LA(i).PL(1 To ILF(i).PL) ’ Punktmomente dimensionieren If ILF(i).PM > 0 Then ReDim LA(i).PM(1 To ILF(i).PM) End If Next ’ Schritt 2: Einlesen der Lastdaten ’ - Initialisierung der Lastenzähler 19.10.2011 Seite 80 Bauinformatik - Teil 1 - Übungsskript / 2011 For i = LBound(ILF) To UBound(ILF) ILF(i).SL = 0 ILF(i).PL = 0 ILF(i).PM = 0 Next ’ - über alle Datensätze ’ Zeiger auf ersten Lastdatensatz setzen i = 1 Do While (Cells(i + i0, 1 + j0) <> "") lf = Cells(i + i0, 1 + j0) ’ Lastfallnummer lesen typ = Cells(i + i0, 3 + j0) ’ Lasttyp lesen ’ Welche Last liegt vor Select Case typ ’ Steckenlast lesen Case 1 ILF(lf).SL = ILF(lf).SL + 1 ’ Zähler inkrementieren LA(lf).SL(ILF(lf).SL).nF = Cells(i + i0, 2 + j0) LA(lf).SL(ILF(lf).SL).q = Cells(i + i0, 4 + j0) LA(lf).SL(ILF(lf).SL).a = Cells(i + i0, 5 + j0) LA(lf).SL(ILF(lf).SL).c = Cells(i + i0, 6 + j0) ’ Punktlast lesen Case 2 ILF(lf).PL = ILF(lf).PL + 1 ’ Zähler inkrementieren LA(lf).PL(ILF(lf).PL).nF = Cells(i + i0, 2 + j0) LA(lf).PL(ILF(lf).PL).P = Cells(i + i0, 4 + j0) LA(lf).PL(ILF(lf).PL).a = Cells(i + i0, 5 + j0) ’ Punktmoment lesen Case 3 ILF(lf).PM = ILF(lf).PM + 1 ’ Zähler inkrementieren LA(lf).PM(ILF(lf).PM).nF = Cells(i + i0, 2 + j0) LA(lf).PM(ILF(lf).PM).M = Cells(i + i0, 4 + j0) LA(lf).PM(ILF(lf).PM).a = Cells(i + i0, 5 + j0) End Select i = i + 1 Loop End Function E. Baeck ’ nächste Lastdaten-Zeile F. LÖSUNGEN ZUM CLAPEYRON-PROBLEM F.4.3 Seite 81 Aufbau der Koeffizientenmatrix Die Koefizientenmatrix wird kompakt unter Ausnutzung von Symmetrie und Bandstruktur aufgebaut. Die Matrix A wird als globale Variable deklariert. ’ Globale Variable Dim A() As Double ’ Koeffizientenmatrix ’ Aufbau der Kooeffizentenmatrix A ’ Der Aufbau erfolgt in kompakter Form unter Ausnutzung von ’ Symmetrie und Bandstruktur ’ Rückgabe: Fehlerkenner = 0 (alles ok) Public Function GenMatA() As Integer Dim i As Integer GenMatA = 0 ’ Für ein Felder ist Lösung bekannt If nFeld < 2 Then GenMatA = 1 Exit Function End If ’ Anlegen der Matrix ReDim A(1 To nFeld - 1, 1 To 2) ’ Setzen der Matrixelemente For i = 1 To nFeld - 1 If i = 1 Then A(1, 1) = 0 Else A(i, 1) = FA(i).L / FA(i).i End If A(i, 2) = 2 * (FA(i).L / FA(i).i + FA(i + 1).L / FA(i + 1).i) Next End Function 19.10.2011 Seite 82 F.4.4 Bauinformatik - Teil 1 - Übungsskript / 2011 Lesen einer kompakt gespeicherten Bandmatrix In der nachfolgenden Route wird aus der Matrix A das Element Aij gelesen. Das Programm berücksichtigt zum einen die Symmetrie der Matrix, zum anderen die kompakte Speicherung der Matrix als symmetrische Bandmatrix (siehe auch Abschnitt 8.5.1). ’ Lesen der Matrixelemente i,j einer globalen Band-Matrix A Function AIJ(i As Integer, j As Integer) As Double ’ i,j -> i,j-i+m+1 mit m=1 ’ i >=j und i-j <=1 Dim m As Integer Dim kj As Integer Dim ki As Integer ’ Banbreite: 1 ’ j-1+m+1 ’ i m = 1 ’ außerhalb des Bandes If Abs(i - j) > m Then AIJ = 0# Exit Function End If ’ 1: oberen Dreieck z.B. If j > i Then ki = j kj = i - j + m + 1 a(1,2) ’ 2: unteres Dreieck + Hauptdiagonale Else ki = i kj = j - i + m + 1 End If AIJ = A(ki, kj) End Function E. Baeck F. LÖSUNGEN ZUM CLAPEYRON-PROBLEM F.4.5 Seite 83 Das Hauptprogramm Die einzelnen Teilschritte, die jeweils in eigenen Unterprogrammen codiert wurden, werden nacheinander in einem Hauptprogramm aufgerufen. Dieses Hauptprogramm liegt (z.Z. noch) in der Ereignisfunktion zum Click -Event. Aus der Ereignisfunktion werden die Tabellen-Ursprungskoordinaten den Programmen weiter gereicht, die aus den Tabellen Eingabedaten entnehmen. Zudem wird nach jedem Teilschritt eine entsprechende Fehlerprüfung durchgeführt, um zu klären, ob eine weiteres Abarbeiten des Programms noch sinnvoll ist. ’ Starten von "Clapeyron" Private Sub CommandButton1_Click() ’ Einlesen der Strukturdaten ierr = MClapeyron.LeseSystem(9, 1) ’ Prüfen der Rückgabe Select Case ierr Case 1: MsgBox "Fehler: kein Feld gefunden!": Exit Sub End Select ’ Einlesen Lastindex ierr = MClapeyron.GenLastIndex(9, 4) ’ Prüfen der Rückgabe Select Case ierr Case 1: MsgBox "Fehler: keine Lasten gefunden!": Exit Sub End Select ’ Einlesen der Lastdaten ierr = MClapeyron.GenLastdaten(9, 4) ’ Aufbau der Kooefizientenmatrix ierr = MClapeyron.GenMatA() End Sub 19.10.2011 Seite 84 G Bauinformatik - Teil 1 - Übungsskript / 2011 Lösungen zum Abschnitt Vektor- und Matrixobjekte In diesem Abschnitt wird das Arbeiten mit Vektoren und Matrizen unter Verwendung von Klassenmodulen (OOP) an Beispielen erläutert (siehe auch Abschnitt 9.2). G.1 Deklaration eines Vektor-Klassenmoduls In VBA ist es nicht möglich auf Feldelemente (Arrays) eines Klassenmoduls als Public zuzugreifen. Aus diesem Grund werden Zugriffsfunktionen als Methoden implementiert, die die internen Feldelemente x() belegen oder auslesen. Dim x() As Double Public n As Integer ’ Vektorkomponenten ’ Vektordimension Private Sub Class_Initialize() Dim i As Integer n = 3 ’ Vektoren aus R3 ReDim x(1 To n) For i = 1 To n x(i) = 0 Next x(1) = 1 ’ Initialisierung mit EV in X-Richtung End Sub ’ Berechnen der Vektorlänge Public Function Laenge() As Double Dim i As Integer Laenge = 0# For i = 1 To n Laenge = Laenge + x(i) * x(i) Next i Laenge = Sqr(Laenge) End Function ’ Vektornormierung Public Function Norm() As Double Dim i As Integer l = Laenge() For i = 1 To n x(i) = x(i) / l Next i Norm = 1 End Function ’ Vektor belegen E. Baeck G. LÖSUNGEN ZUM ABSCHNITT VEKTOR- UND MATRIXOBJEKTE Seite 85 Public Function SetX(dX() As Double) As Integer Dim ie As Integer ie = n If UBound(dX) < n Then ie = UBound(dX) For i = 1 To ie x(i) = dX(i) Next i SetX = 1 End Function ’ Vektor auslesen Public Function GetX(dX() As Double) As Integer Dim ie As Integer ie = n If UBound(dX) < n Then ie = UBound(dX) For i = 1 To ie dX(i) = x(i) Next i GetX = 1 End Function ’ Rotieren eines Vektors mit Drehmatrix "m" Public Function Rot(m As Matrix) As Integer Dim s As Double Dim xs() As Double ReDim xs(n) For i = 1 To n xs(i) = 0# For j = 1 To n xs(i) = xs(i) + m.GetK(i, j) * x(j) Next j Next i For i = 1 To n x(i) = xs(i) Next i Rot = 1 End Function ’ Zugriffsfunktion auf Feld x(i) Public Function xi(i As Integer) As Double xi = x(i) End Function ’ Skalarprodukt mit anderem Vektor 19.10.2011 Seite 86 Bauinformatik - Teil 1 - Übungsskript / 2011 Public Function sprod(v As Vektor) As Double Dim s As Double ’ Skalarprodukt s = 0 For i = 1 To n s = s + x(i) * v.xi(i) Next sprod = s End Function ’ Testausgabe Public Function List() As Integer Debug.Print "Vektor: " + Format(x(1), "0.0000") + "; " + _ Format(x(2), "0.0000") + "; " + _ Format(x(3), "0.0000") + "; " List = 1 End Function G.2 Deklaration eines Matrix-Klassenmoduls In VBA ist es nicht möglich auf Feldelemente (Arrays) eines Klassenmoduls als Public zuzugreifen. Aus diesem Grund werden Zugriffsfunktionen als Methoden implementiert, die die internen Feldelemente x() belegen oder auslesen. ’ Klasse quadratischer n x n-Matrizen ’ Dim x() As Double Dim n As Integer Dim i, j As Integer Private Sub Class_Initialize() n = 3 ReDim x(1 To n, 1 To n) As Double For i = 1 To n For j = 1 To n x(i, j) = 0# Next j Next i End Sub ’ Belegen der Matrixelemente Public Function SetX(dX() As Double) As Integer For i = 1 To n For j = 1 To n x(i, j) = dX(i, j) Next j E. Baeck G. LÖSUNGEN ZUM ABSCHNITT VEKTOR- UND MATRIXOBJEKTE Seite 87 Next i SetX = 1 End Function ’ Lesen der Matrixelemente Public Function GetX(dX() As Double) As Integer For i = 1 To n For j = 1 To n dX(i, j) = x(i, j) Next j Next i GetX = 1 End Function ’ Lesen eines Matrixelements Public Function GetK(ByVal i1 As Integer, ByVal i2 As Integer) As Double GetK = x(i1, i2) End Function ’ Testausdruck für den Fall n x n Public Function List() As Integer Debug.Print "Matrix: " + Format(x(1, Format(x(1, Format(x(1, Debug.Print " " + Format(x(2, Format(x(2, Format(x(2, Debug.Print " " + Format(x(3, Format(x(3, Format(x(3, List = 1 End Function 1), 2), 3), 1), 2), 3), 1), 2), 3), "0.0000") "0.0000") "0.0000") "0.0000") "0.0000") "0.0000") "0.0000") "0.0000") "0.0000") + + + + + + + + + "; "; "; "; "; "; "; "; "; " " " " " " " " " + _ + _ + _ + _ + _ + _ 19.10.2011 Seite 88 G.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Programm Vektor 1 Das Programm Vektor 1 erzeugt eine Instanz des Vektor-Klassemoduls. Der Vektor wird initialisiert. Es wird die Vektorlänge berechnet. Im zweiten Teil des Programms wird der Vektor normiert und zur Prüfung erneut die Vektorlänge berechnet und ausgegeben. ’ Testprogramm für Klasse Vektor Sub vektor1() Dim l As Double Dim v As Vektor ’ Vektorlänge ’ Zeiger Vektor Dim x(1 To 3) As Double x(1) = 2: x(2) = 2: x(3) = 0 Set v = New Vektor ’ Instanz von Vektor anlegen l = v.Laenge() Call v.List ’ Vektorausgabe in Direktfenster Debug.Print "Länge: " + Format(l, "0.000") r = v.SetX(x) ’ Daten setzen l = v.Laenge() Call v.List ’ Vektorausgabe in Direktfenster Debug.Print "Länge: " + Format(l, "0.000") Call v.Norm Call v.List l = v.Laenge() Debug.Print "Länge: End Sub E. Baeck ’ ’ ’ " Normierung des Vektors Vektorausgabe in Direktfenster Vektorlänge berechnen + Format(l, "0.000") G. LÖSUNGEN ZUM ABSCHNITT VEKTOR- UND MATRIXOBJEKTE G.4 Seite 89 Programm Vektor Drehen Das Programm Vektor Drehen erzeugt eine Instanz des Vektor-Klassemoduls v und eines MatrixKlassenmoduls D. Der Vektor wird initialisiert. Die Matrix wird mit den Matrixelementen einer 2d-Drehmatrix (Drehen um (0,0) um die z-Achse) belegt. Der Drehoperator wird in Form der Matrixmultiplikation v 0 = D · v ausgeführt. ’ Vektor- und Matrixobjekte: ’ - 2D-Drehmatrix, Drehen eines Vektors Sub Vektor_Drehen() Dim phi, co, si As Double Dim x(1 To 3, 1 To 3) As Double Dim y(1 To 3) As Double ’ Drehwinkel phi = Atn(1#) / 45# * 90# ’ Drehmatrix Dim m As Matrix ’ Vektor Dim v As Vektor ’ Initialisierungen Set m = New Matrix Set v = New Vektor co = Cos(phi) si = Sin(phi) x(1, x(2, x(3, y(1) 1) = co: x(1, 2) 1) = si: x(2, 2) 1) = 0#: x(3, 2) = 1#: y(2) = 0#: = -si: x(1, 3) = 0# = co: x(2, 3) = 0# = 0#: x(3, 3) = 1# y(3) = 0# ’ Setzen der Objektwerte n = m.SetX(x) n = v.SetX(y) ’ Ausgabe der Objekte n = m.List() n = v.List() ’ Multiplikation: v := m*v n = v.Rot(m) ’ Ausgabe des Vektors n = v.List() End Sub 19.10.2011 Seite 90 H Bauinformatik - Teil 1 - Übungsskript / 2011 Lösungen zum Abschnitt Rahmen und Collection In diesem Abschnitt wird die Implementierung des Speicherkonzepts zum Rahmenbeispiel dargestellt. Es werden die Klassenmodule Stab und Knoten angelegt (siehe Abschnitt 9.4). Die Assoziation zwischen Stab und Knoten erfolgt über die Objektzeiger der Knoten-Instanzen. Stäbe und Knoten werden in den VBA-Listen , den Collections, gespeichert. H.1 Deklaration des Stab-Klassenmoduls Ein Stab-Objekt erhält die Attribute Stabnummer (Nr ), E-Modul (E ) und Querschnittsfläche (a) sowie die Knoten-Instanz-Zeiger KnA und KnB. Die Methode Laenge ermittelt die Stablänge über die Koordinatenwerte der assoziierten KnotenInstanzen. Public Public Public Public Public Nr As Integer E As Double a As Double KnA As Knoten KnB As Knoten ’ ’ ’ ’ ’ Nummer des Stabes E-Modul Fläche Knoten A Knoten B ’ Berechnen der Stablänge Public Function Laenge() As Double Laenge = Sqr((KnA.x - KnB.x) ^ 2 + (KnA.y - KnB.y) ^ 2) End Function H.2 Deklaration des Knoten-Klassenmoduls Ein Knoten erhält die Attribute Knotennummer (Nr ) und die Knotenkoordinaten (x und y). Die Methode Verschieben addiert einen Translationsvektor auf den Ortsvektor des Knotens (Koordindatenwerte). Public Nr As Integer Public x As Double Public y As Double ’ Nummer des Knotens ’ x-Koordinate ’ y-Koordinate ’ Verschieben eines Knotens Public Sub Verschieben(dx As Double, dy As Double) x = x + dx y = y + dy End Sub E. Baeck H. LÖSUNGEN ZUM ABSCHNITT RAHMEN UND COLLECTION H.3 Seite 91 Implementierung des Anwendungsprogramms Das Anwendungsprogramm besteht aus den folgenden drei Teilprogrammen. • Einlesen liest die Daten aus der Tabelle, erzeugt die Instanzen der Stäbe bzw. Knoten und speichert diese in die Stabliste SL bzw. Knotenliste KL. Als Parameter erwartet das Programm den Offset (i0,j0) des Eingabebereichs der Tabelle. • Ausgabe schreibt die Daten der Stäbe bzw. Knoten, die in den Listen (Collections) gespeichert wurden in den Ausgabebereich der Tabelle. Zudem wird noch die Länge der Stäbe ausgegeben. Als Parameter erwartet das Programm den Offset (i0,j0) des Ausgabebereichs der Tabelle. • Verschieben addiert den in der Tabelle eingegebenen Verschiebungsvektor auf alle Knotenkoordinaten. Als Parameter werden die Verschiebungen in x- bzw. y-Richtung erwartet. • StabAnzahl ermittelt als Hilfsfunktion die Anzahl der bereits eingegebenen Stäbe. Wurden keine Stäbe eingelesen, so wird vor dem Ausführen der Verschiebungsfunktion der Datenbestand eingelesen. H.3.1 Die Listen Die Listen (Collection) werden als globale Variablen angelegt, damit sie von allen Programmen des Moduls erreichbar sind. Dim KL As New Collection Dim SL As New Collection H.3.2 ’ Anlegen der Knotenliste ’ Anlegen der Stabliste Die Funktion Einlesen Es werden zunächst die Listen der Knoten und Stäbe zurückgesetzt, d.h. es werden alle Instanzen mit der Item-Funktion gelesen und gelöscht (=nothing). Der Indexeintrag der Collection wird mit der Funktion Remove entfernt.33 Im nächsten Schritt werden zunächst die Knotendaten eingelesen und die Knotenliste aufgebaut. Die Knoten werden für den Aufbau der Stabdaten benötigt. Als letzter Schritt werden die Stabdaten eingelesen, hierbei werden die Knotennummern in Knotenverweise gewandelt. Diese werden aus der bereits existierenden Knotenliste abgegriffen. Die Parameter i0 und j0 sind Zeilen- und Spaltenoffset des Eingabebereichs der Tabelle. 33 Da beim Löschen in einer Liste die verbleibenden Einträge zum Listenkopf rücken, wenn vor ihnen ein Eintrag gelöscht wird, wird mit der Anzahl der in der Liste gespeicherten Elemente immer der Erste Eintrag gelöscht. 19.10.2011 Seite 92 Bauinformatik - Teil 1 - Übungsskript / 2011 ’ Einlesen der Daten aus Tabelle Public Sub Einlesen(i0 As Integer, j0 As Integer) Dim s As Stab Dim k As Knoten ’ nur Stabzeiger! ’ Knotenzeiger ’ Liste der Knoten zurücksetzen N = KL.Count For i = 1 To N Set k = KL(1) ’ Zeiger holen Set k = Nothing ’ Objekt löschen KL.Remove (1) ’ Index löschen Next ’ Liste der Stäbe zurücksetzen N = SL.Count For i = 1 To N Set s = SL(1) ’ Zeiger holen Set s = Nothing ’ Objekt löschen SL.Remove (1) ’ Index löschen Next ’ Einlesen der Knoten iZ = 1 ’ 1. Zeile Do While (Cells(i0 + iZ, j0 + 7) <> "") Set k = New Knoten ’ neus Knotenobjekt anlegen k.Nr = Cells(i0 + iZ, j0 + 7) k.x = Cells(i0 + iZ, j0 + 8) k.y = Cells(i0 + iZ, j0 + 9) iZ = iZ + 1 ’ nächste Zeile KL.Add Item:=k, key:="K" & k.Nr Loop ’ Einlesen der Stäbe iZ = 1 ’ 1. Zeile Do While (Cells(i0 + iZ, j0 + 1) <> "") Set s = New Stab ’ neues Stabobjekt anlegen s.Nr = Cells(i0 + iZ, j0 + 1) s.E = Cells(i0 + iZ, j0 + 2) s.a = Cells(i0 + iZ, j0 + 3) nA = Cells(i0 + iZ, j0 + 4) nB = Cells(i0 + iZ, j0 + 5) Set s.KnA = KL("K" & nA) E. Baeck H. LÖSUNGEN ZUM ABSCHNITT RAHMEN UND COLLECTION Seite 93 Set s.KnB = KL("K" & nB) iZ = iZ + 1 ’ nächste Zeile SL.Add Item:=s, key:="S" & s.Nr Loop End Sub H.3.3 Die Funktion Ausgabe In einer Schleife über die Stabliste werden alle Stab-Instanzen aus der Liste abgegriffen. Zunächst werden Stab-Attribute in den Ausgabebereich der Tabelle geschrieben. Die Knotenkoordinaten werden über die Verweise aus der assoziierten Knoteninstanz abgegriffen und ausgegeben. Die Länge des Stabes liefert die Methode Laenge des Stabes, die ihrerseits auf die Knotenkoordinaten der assoziierten Knoten-Instanzen verweisen (Abschnitt H.1). Die Parameter i0 und j0 sind Zeilen- und Spaltenoffset des Ausgabebereichs der Tabelle. ’ Ausgabe der Daten in die Tabelle Public Sub Ausgabe(i0 As Integer, j0 As Integer) Dim s As Stab ’ nur Stabzeiger! ’ über alle Stäbe For i = 1 To SL.Count Set s = SL(i) Cells(i0 Cells(i0 Cells(i0 Cells(i0 Cells(i0 Cells(i0 Cells(i0 Cells(i0 + + + + + + + + i, i, i, i, i, i, i, i, ’ Stab holen j0 j0 j0 j0 j0 j0 j0 j0 + + + + + + + + 1) 2) 3) 4) 5) 6) 7) 8) = = = = = = = = s.Nr s.E s.a s.KnA.x s.KnA.y s.KnB.x s.KnB.y s.Laenge() Next End Sub 19.10.2011 Seite 94 Bauinformatik - Teil 1 - Übungsskript / 2011 H.3.4 Die Funktion Verschieben In einer Schleife über die Knotenliste werden alle Knoten-Instanzen aus der Liste abgegriffen. Für jeder dieser Knoten-Instanzen wird die Knoten-Methode Verschieben aufgerufen (Abschnitt H.2). ’ Knoten verschieben Public Sub Verschieben(vx As Double, vy As Double) Dim k As Knoten ’ über alle Knoten For i = 1 To KL.Count Set k = KL(i) Call k.Verschieben(vx, vy) ’ Knoten holen ’ und verschieben Next End Sub H.3.5 Die Funktion StabAnzahl Mit der Funktion StabAnzahl ermittelt die Verschieben-Ereignisfunktion, ob bereits StabInstanzen in die Stabliste gespeichert wurden. Hierfür ermittelt StabAnzahl über die Methode Count die Anzahl der Listenelemente. ’ Anzahl der Stäbe ermitteln Public Function StabAnzahl() As Integer StabAnzahl = SL.Count End Function H.3.6 Die Ereignisfunktionen Die erste Ereignisfunktion34 wird aufgerufen, wenn die Schaltfläche Einlesen der Daten betätigt wird. Mit Offset (4,0) wird der Eingabebereich der Tabelle ausgelesen. Die Daten werden in Listen gespeichert und in aufbereiteter Form mit Offeset (22,0) in den Ausgabebereich der Tabelle eingetragen Private Sub CommandButton1_Click() Call Staebe.Einlesen(4, 0) Call Staebe.Ausgabe(22, 0) End Sub 34 Die Ereignisfunktionen stehen im Code-Bereich des Tabellenobjekts, im Order Microsoft Excel Objekte. E. Baeck H. LÖSUNGEN ZUM ABSCHNITT RAHMEN UND COLLECTION Seite 95 Die zweite Ereignisfunktion wird aufgerufen, wenn die Schaltfläche Verschieben betätigt wird. Zunächst werden die Daten des Verschiebungsvektors (vx,vy) aus der Tabelle gelesen. Falls keine Stab-Instanzen in der Stabliste gefunden werden, wird der Eingabebereich der Tabelle eingelesen, die Datenstrukturen werden aufgebaut. Im zweiten Schritt werden die Knoten verschoben, im dritten die Daten des verschobenen Rahmens in den Ausgabebereich der Tabelle eingetragen. Private Sub CommandButton2_Click() Dim vx As Double Dim vy As Double vx = Range("VX") vy = Range("VY") ’ Verschiebung in x ’ Verschiebung in y If Staebe.StabAnzahl < 1 Then Call Staebe.Einlesen(4, 0) End If Call Staebe.Verschieben(vx, vy) Call Staebe.Ausgabe(22, 0) End Sub 19.10.2011 Seite 96 I Bauinformatik - Teil 1 - Übungsskript / 2011 Lösungen zum Abschnitt 2-fach verkettete Listen In diesem Abschnitt wird die Implementierung einer 2-fach verketteten Liste dargestellt. Liste besteht aus zwei Klassenmodulen. Der Klassenmodul VListe ist das Hauptobjekt, die einzelnen Listenmethoden enthält. Der Klassenmodul VNode dient als Listenelement, zum einen Bestandteil der Listentopologie ist, zum anderen die Zeiger auf die Instanzen einzuspeichernden Datenobjekte erhält (siehe Abschnitt 9.5). I.1 Die das das der Deklaration des VNode-Klassenmoduls Der Listenknoten enthält nur eine Methode, die Initialisierung. Alle Zeiger werden auf nothing gesetzt. Der Knoten ist standardmäßig ein Datenknoten. Public prv As Object Public nxt As Object Public Dat As Object ’ Zeiger auf vorhergehenden Knoten ’ Zeiger auf nachfolgenden Knoten ’ Zeiger auf Daten Public Ken As Integer ’ 0: Datenknoten ’ 1: Startknoten ’ 2: Endknoten Private Sub Class_Initialize() Set prv = Nothing Set nxt = Nothing Set Dat = Nothing Ken = 0 End Sub I.2 Deklaration des VListe-Klassenmoduls Der Klassenmodul VListe implementiert die Container-Klasse. In der Instanz-Initialisierung wird Start- und Endknoten in die Liste aufgenommen. Beide Knoten werden gegenseitig verzeigert. Public Count As Integer Public N1 As VNode Public NL As VNode ’ Anzahl der Datenknoten ’ Startknoten ’ Endknoten Private Sub Class_Initialize() Set N1 = New VNode: N1.Ken = 1 Set NL = New VNode: NL.Ken = 2 ’ Startknoten setzen ’ Endknoten setzen Set N1.nxt = NL Set NL.prv = N1 ’ Liste ist leer ’ Start -> Ende End Sub E. Baeck I. LÖSUNGEN ZUM ABSCHNITT 2-FACH VERKETTETE LISTEN I.2.1 Seite 97 Daten am Listenkopf einfügen Implementierung nach Abschnitt 9.5.2. ’ Objekt am Listenkopf einfügen Public Function AddFirst(Dat As Object) As Integer Dim N As New VNode ’ Neuen Knoten erzeugen Set N1.nxt.prv = N Set N.nxt = N1.nxt Set N1.nxt = N ’ ... ist Vorgänger des ehemals ersten ’ ... der Nachfolger ist eben dieser ’ ... der neue Knoten ist nun erster der Liste Set N.prv = N1 Set N.Dat = Dat ’ ... der Vorgänger des ersten ist der Startknoten ’ ... und dann der Zeiger auf die Daten Count = Count + 1 AddFirst = Count ’ ... damit Liste um 1 vergrößert End Function I.2.2 Daten am Listenende einfügen Implementierung nach Abschnitt 9.5.2. ’ Objekt am Listenende einfügen Public Function AddLast(Dat As Object) As Integer Dim N As New VNode ’ Neuen Knoten erzeugen Set NL.prv.nxt = N Set N.prv = NL.prv Set NL.prv = N ’ ... ist nächster des letzten ’ ... vorhergehender ist vormals letzter ’ ... wird neuer letzter Knoten Set N.nxt = NL Set N.Dat = Dat ’ ... Listenende zeigt auf neuen Knoten ’ ... und Datenzeiger setzen Count = Count + 1 AddLast = Count ’ ... damit Liste um 1 vergrößert End Function 19.10.2011 Seite 98 I.2.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Vorwärtsiterator Implementierung nach Abschnitt 9.5.4. Die Implementierung setzt voraus, dass die zurückgegebenen Listenknoten (Instanz VNode) vom aufrufenden Programm nicht verändert werden. ’ Ersten Knoten holen Public Function GetFirst(Nd As VNode) As Integer If N1.nxt.Ken = 2 Then GetFirst = 0 Else Set Nd = N1.nxt GetFirst = 1 End If ’ ’ ’ ’ ... Listenende (Kein Datenknoten vorh.) ... 0: Ende ... ersten Datenknoten holen ... 1: Daten vorhanden End Function ’ Nächsten Knoten holen Public Function GetNext(Nd As VNode) As Integer If Nd.nxt.Ken = 2 Then GetNext = 0 Else Set Nd = Nd.nxt GetNext = 1 End If ’ ... Listenende (Kein weiterer Datenknoten vorh.) ’ ... 0: Ende ’ ... nächsten Datenknoten holen ’ ... 1: Daten vorhanden End Function In nachfolgendem Beispiel wird eine Liste mit Stab-Instanzen iteriert. ... Dim L As new VListe Dim Nd As New VNode ’ ... Instanz der Liste ’ ... Knoteninstatnz ... Aufbau der Liste ... ’ Liste vorwärts iterieren nret = L.GetFirst(Nd) ’ Do While (nret > 0) ’ Debug.Print " Stab: " & Nd.Dat.Nr ’ nret = L.GetNext(Nd) ’ Loop ... E. Baeck ... ... ... ... holen des ersten Knotens nächsten holen solange das Ende der Liste nicht erreicht ist. Zuvor Stabnummer ausgeben I. LÖSUNGEN ZUM ABSCHNITT 2-FACH VERKETTETE LISTEN I.2.4 Seite 99 Einfügen eines Knotens Implementierung nach Abschnitt 9.5.2. Die Implementierung setzt voraus, dass die zurückgegebenen Listenknoten (Instanz VNode) vom aufrufenden Programm nicht verändert werden. Ein neuer Listenknoten ist im aufrufenden Programm zu erzeugen und mit den entsprechenden Daten zu versehen. Das Einfügen des Listenknotens in die Liste über nimmt die Methode Insert. ’ Knoten einfügen vor Referenzknoten Public Function Insert(Nd As VNode, NdNew As VNode) As Integer If Nd.Ken = 1 Then Insert = 0 Exit Function End If ’ ... Einfügen vor Start nicht möglich Set Set Set Set ’ ... prv- von Nd soll auf Ndnew zeigen ’ ... Belegen der Zeiger des neuen Knotens Nd.prv.nxt = NdNew NdNew.prv = Nd.prv NdNew.nxt = Nd Nd.prv = NdNew Count = Count + 1 Insert = 1 ’ ... NdNew wird vor Nd eingefügt ’ ... damit Liste um 1 vergrößert End Function 19.10.2011 Seite 100 J Bauinformatik - Teil 1 - Übungsskript / 2011 Lösungen zu Sortieralgorithmen In diesem Abschnitt wird das Laufzeitverhalten der Sortieralgorithmen SelectSort, BubbleSort und QuickSort verglichen. Mit der Schaltfläche Zufallszahlen werden Zufallszahlen im Bereich des vorgegebenen Zahlenintervalls erzeugt. Mit den weiteren Schaltflächen werden die drei verschiedenen Sortieralgorithmen aufgerufen. Die generierten Zufallszahlen werden nach Größe aufsteigend sortiert. Es wird jeweils die Anzahl der erfolgten Vertauschungen ausgegeben. Der erforderliche Aufwand der hier betrachteten Sortierverfahren SelectSort, BubbleSort und QuickSort ergibt sich zu Abbildung 52: Vergleich dreier Sortieralgorithmen • SelectSort benötigt n2 /2 Vergleiche und n Vertauschungen. • BubbleSort benötigt im ungünstigsten Fall n2 /2 Vergleiche und n2 /2 Vertauschungen. • Quicksort benötigt im Mittel 2 · n · Ln(n) Vergleiche. Der Aufwand der Vergleiche bei elementaren Sortierverfahren ist ca. von gleicher Größenordnung. Dem gegenüber liegt der Aufwand der Vergleiche bei der QuickSort-Sortierung bei Orndung n · Log(n). Bei beispielsweise 300 Zufallszahlen35 aus dem Intervall 1 bis 1000 benötigen SelectSort und BubbleSort 44850 Vergleiche (siehe Abbildung 52). Demgegenüber benötigt Quicksort 605 Vergleiche.36 35 Die für die Sortierung erzeugten Reihen von Zufallszahlen sind in den vorliegenden Sortierungen unterschiedlich. Das Laufzeitverhalten ist jedoch annähernd unabhängig von der gewählten Zufallszahlenreihe. 36 Quicksort benötigt ca. n · Log(n) Vergleiche, die beiden anderen Sortierungen benötigen ca. n2 /2 Vergleiche. Bei n = 1000 ergibt sich ein Leistungsquotient von (n · Log(n))/n2 /2 = 2 · Log(n)/n = 2 · 3/1000 = 0, 6%, d.h. der Aufwand für Quicksort im Vergleich zu den beiden anderen Sortierverfahren liegt bei 1000 zu sortierenden Elementen demnach unter 1%. E. Baeck J. LÖSUNGEN ZU SORTIERALGORITHMEN J.1 Seite 101 Die Ereignisfunktionen Die Ereignisfunktionen werden aus dem Modul Sortieren aufgerufen. Als Parameter werden die Offsets des Bereichs der Tabelle übergeben, in der die Zufallszahlen ausgegeben werden. Zudem wird die Anzahl der generierten Zufallszahlen aus dem Eingabebereich der Tabelle mit Range gelesen und übergeben. Private Sub CommandButton1_Click() Call Sortieren.Zufallszahlen(9, 0, Range("SORTANZ")) End Sub Private Sub CommandButton2_Click() Call Sortieren.SelectSortieren(9, 0, Range("SORTANZ")) End Sub Private Sub CommandButton3_Click() Call Sortieren.QuickSortieren(9, 0, Range("SORTANZ")) End Sub Private Sub CommandButton4_Click() Call Sortieren.BubbleSortieren(9, 0, Range("SORTANZ")) End Sub J.2 Generierung der Zufallszahlen Die Zufallszahlen können in VBA mit der Funktion Rnd 37 erzeugt werden. Rnd liefert hierfür eine Zufallszahl38 . Die genierten Zufallszahlen werden wie folgt in das vorgegebene Intervall skaliert. Z = (Zbis − Zvon ) · Zrnd + Zvon (74) Das Intervall der Zufallszahlen wird aus der Tabelle über Range abgegriffen. Bevor die Zufallszahlen generiert und die Tabelle geschrieben werden, wird diese im Ausgabebereich zunächst von Altdaten befreit, d.h. es wird die Hilfsfunktion Loeschen aufgerufen. Es wird die erste Spalte nach Einträgen untersucht. Falls ein Eintrag gefunden wird, wird die Anzahl der vorgegebenen Spalten gelöscht. Falls kein Eintrag gefunden wird, geht das Programm davon aus, dass das Ende des zu löschenden Bereichs erreicht wurde. 37 Reihen von Zufallszahlen sind dann reproduzierbar, wenn der Zufallszahlengenerator nicht mit einer zufälligen Information vorbesetzt wird. Dies erfolgt durch Aufruf der Routine Randomize 38 Ein Zufallszahlen-Generator erzeugt Pseudo-Zufallszahlen. Pseudo-Zufallszahl bedeutet, dass bei exakt identischen Eingangsdaten (Zeitwerte etc.) der Zufallszahlen-Generators Zahlen reproduzierbar erzeugt. Da die Eingangsdaten des Zufallszahlen-Generators kaum reproduzierbar und somit zufällig sind, die Algorithmen jedoch deterministisch, werden die generierten Zahlen nicht als Zufallszahlen sondern als Pseudo-Zufallszahlen bezeichnet. Der Einfachheit halber sind hier Zufallszahlen generell als Pseudo-Zufallszahlen zu verstehe. 19.10.2011 Seite 102 Bauinformatik - Teil 1 - Übungsskript / 2011 ’ Erzeugen von Zufallszahlen Sub Zufallszahlen(i0 As Integer, j0 As Integer, nAnz As Integer) Dim dVon As Double Dim dBis As Double dVon = Range("S_VON") dBis = Range("S_BIS") ’ Tabelle löschen i = Util.Loeschen(i0, j0, 2) ’ Zufallszahlen generieren call Randomize For i = 1 To nAnz Cells(i0 + i, 1) = i Cells(i0 + i, 2) = (dBis - dVon) * Rnd + dVon Next End Sub Nachfolgend das Hilfsprogramm Loeschen, dass einen Tabellenbereich löscht unter Vorgabe des Zeilen- und Spaltenoffset sowie der Spaltenanzahl. ’ Löschen eines Tabellenbereichs Public Function Loeschen(i0 As Integer, j0 As Integer, nSpalten As Integer) _ As Integer Dim nZeile As Integer Dim i As Integer ’ Zeilenzähler nZeile = 1 ’ erste Zeile ’lokal’ ’ über alle Zeilen Do Until Cells(i0 + nZeile, j0 + 1) = "" ’ über die Spalten For i = 1 To nSpalten Cells(i0 + nZeile, j0 + i) = "" Next nZeile = nZeile + 1 Loop Loeschen = nZeile End Function E. Baeck J. LÖSUNGEN ZU SORTIERALGORITHMEN J.3 Seite 103 Sortieralgorithmen In diesem Abschnitt wird eine VBA-Implementierung der Sortieralgorithmen SelectSort (siehe 6.1), BubbleSort (siehe 6.2) und QuickSort (siehe 10.1) dargestellt. Um die Leistungsfähigkeit der Algorithmen darzustellen werden die globalen Variablen nT ausch und nV ergleich als Zähler für Vertauschungen und Vergleiche eingeführt. Die Zähler werden jeweils vor der Sortierung zurückgesetzt. Die Vertauschung der Zufallszahlen erfolgt in folgender Routine, die von allen implementierten Sortierverfahren aufgerufen wird. ’ Datensätze tauschen Sub tausche(i, j) For k = 1 To 2 s = Cells(i, k) Cells(i, k) = Cells(j, k) Cells(j, k) = s Next nTausch = nTausch + 1 End Sub J.3.1 Implementierung von SelectSort ’ Hauptprogramm: Selectsort Sub SelectSortieren(i0 As Integer, j0 As Integer, nAnz As Integer) nTausch = 0 nVergleich = 0 ’ Protokoll Cells(i0 + 1, j0 + 3) = "Sortierung in Arbeit..." ’ über alle Auswahlpositionen For i = 1 To nAnz - 1 x = i ’ extremale Größe aus Intervall ermitteln For j = i + 1 To nAnz dvj = Cells(i0 + j, 2) dvx = Cells(i0 + x, 2) If dvj < dvx Then x = j nVergleich = nVergleich + 1 Next ’ extremale Größe an aktuelle Spitzenposition tauschen Call tausche(i0 + i, i0 + x) Next 19.10.2011 Seite 104 Bauinformatik - Teil 1 - Übungsskript / 2011 ’ Protokoll Cells(i0 + 1, j0 + 3) = Format(nVergleich, "0") + " Vergleiche und " + _ Format(nTausch, "0") + " Vertauschungen (SelectSort)" End Sub J.3.2 Implementierung von BubbleSort ’ Hauptprogramm: Bubblesort Sub BubbleSortieren(i0 As Integer, j0 As Integer, nAnz As Integer) nTausch = 0 nVergleich = 0 ’ Protokoll Cells(i0 + 2, j0 + 3) = "Sortierung in Arbeit..." ’ über alle Auswahlpositionen For i = nAnz To 1 Step -1 ’ Auswahlgebiet For j = 2 To i dV1 = Cells(i0 + j - 1, j0 + 2) dv2 = Cells(i0 + j, j0 + 2) nVergleich = nVergleich + 1 If dV1 > dv2 Then Call tausche(i0 + j - 1, i0 + j) End If Next Next ’ Protokoll Cells(i0 + 2, j0 + 3) = Format(nVergleich, "0") + " Vergleiche und " + _ Format(nTausch, "0") + " Vertauschungen (BubbleSort)" End Sub E. Baeck J. LÖSUNGEN ZU SORTIERALGORITHMEN J.3.3 Seite 105 Implementierung von QuickSort ’ Hauptprogramm: Quicksort Sub QuickSortieren(i0 As Integer, j0 As Integer, nAnz As Integer) nTausch = 0 nVergleich = 0 ’ Protokoll Cells(i0 + 3, j0 + 3) = "Sortierung in Arbeit..." ’ Sortierung Call qsort(i0 + 1, i0 + nAnz) ’ Protokoll Cells(i0 + 3, j0 + 3) = Format(nVergleich, "0") + " Vergleiche und " + _ Format(nTausch, "0") + " Vertauschungen (QuickSort)" End Sub Im folgenden wird das Programm qsort dargestellt, das rekursiv ein Intervall der zu sortierenden Menge bezogen auf einen Teiler vorsortiert.39 ausgeschaltet würde. ’ Vorsortierung des Bereichs von l (links) bis r (rechts) Sub qsort(l, r) ’ Teilfeld enthält nur ein Element If r <= l Then Exit Sub ’ Abbruch der Rekursion ’ hole das teilende Element v = Cells(r, 2) ’ Laufvariablen i = l - 1 j = r ’ Umsortierung Do ’ mit i von links nach rechts Do i = i + 1 w = Cells(i, 2) nVergleich = nVergleich + 1 Loop While w < v and i < r 39 In der vorliegenden Implementierung in EXCEL-VBA schlägt vor allem das Vertauschen zu Buche, da das Vertauschen zweier Zahlen eine unmittelbare Aktualisierung der Tabelle nach sich zieht. Somit ist das Laufzeitverhalten von BubbleSort mit deutlichem Abstand das schlechteste, es benötigt im ungünstigsten Fall (n2 /2) Vertauschungen. Obwohl SelectSort nur n Vertauschungen benötigt, überkompensieren die benötigten (n2 /2) Vergleiche die 2 · n · Ln(n) Vertauschungen von QuickSort. Das Laufzeitverhalten von BubbleSort könnte im Vergleich zu den anderen Sortierverfahren angehoben werden, wenn das automatische Aktualisieren der EXCEL-Tabelle 19.10.2011 Seite 106 ’ mit j von rechts nach links Do j = j - 1 w = Cells(j, 2) nVergleich = nVergleich + 1 Loop While w > v and j > l ’ bereits vorsortiert? If i >= j Then Exit Do Call tausche(i, j) Loop ’ Setze r an endgültige Position Call tausche(i, r) ’ das ganze dann auf Teilgebiete anwenden ’ - linkes Teilgebiet Call qsort(l, i - 1) ’ - linkes Teilgebiet Call qsort(i + 1, r) End Sub E. Baeck Bauinformatik - Teil 1 - Übungsskript / 2011 K. LÖSUNG ZUR BRENDT’SCHEN FORMEL K Seite 107 Lösung zur Brendt’schen Formel In diesem Abschnitt eine Implementierung der Brendt’schen Formel (Gleichung 12) gegeben. Mit der ersten Schaltfläche wird die einzulesende Datei, die die Profildaten enthält, festgelegt. Abbildung 53: Einlesen einer sequentiellen Datei Mit der zweiten Schaltfläche wird das Einlesen der Profildaten aus der vorgegebenen Datei und die Berechnung des Torsionsträgheitsmomentes nach 2. Brendt’scher Formel angestoßen. K.1 Die Ereignisfunktion zur Festlegung des Dateinamens Um den Dateinamen der einzulesenden Datei festzulegen wird in der Ereignisfunktion die Methode GetOpenFilename des EXCEL-Application-Objekts eingesetzt. Private Sub CommandButton1_Click() datei$ = Application.GetOpenFilename( _ filefilter:="Textdatei (*.txt),*.txt") If Not datei$ = "Falsch" Then Range("DNAME") = datei$ Abbildung 54: Dateinamen festlegen End If End Sub K.2 Die Ereignisfunktion zu Datenimport und Berechnung Wurde der Dateinamen vereinbart, kann die zweite Funktion Lesen aus dem Modul Brendt gestartet werden. Sie importiert die Daten aus der vereinbarten Textdatei und berechnet die gewünschten Größen nach der 2. Brendt’schen Formel. Im Beispiel der Abbildung 55 wird ein rechteckiges Kastenprofil mit koinstanter Blechdicke beschrieben. Abbildung 55: Eingabedaten Private Sub CommandButton2_Click() Call Brendt.Lesen End Sub 19.10.2011 Seite 108 K.3 Bauinformatik - Teil 1 - Übungsskript / 2011 Die Datenstruktur Die Konturknoten des Profils, d.h. je ein Datensatz der Datei, werden in Datenstrukturen (Type) gespeichert. Da mehrere Knoten zu speichern sind, wird ein Feld als globale Variable des Typs KKNOTEN angelegt. Die Anzahl der Knoten soll dynamisch zur Laufzeit des Programms vereinbart werden, d.h. der Indexbereich des Feldes wird zunächst leer gelassen (K()). ’ Knoten der Kontur Type KKNOTEN y As Double z As Double t As Double End Type ’ Variable der Kontur Dim K() As KKNOTEN K.4 Einlesen der Daten aus der Profil-Textdatei Das Hauptprogramm der Verarbeitung Lesen wird aus dem Modul Brendt gestartet, somit ist es als Public zu vereinbaren. 1. In einem ersten Schritt wird zunächst die Anzahl der Konturknoten ermittelt. Ein Knoten wird im Knotenfeld angelegt (Redim K(1 to 1)). 2. In einem zweiten Schritt wird die Datei geöffnet. Es werden die Datensätze, d.h. die Anzahl der Knoten in der Datei ermittelt. Für diese und den gedoppelten 1. Knoten, da zyklisches Problem, wird der Speicherplatz angelegt. 3. Im dritten Schritt wird die Datei erneut geöffnet. Nun werden die Daten in die Datenstruktur gelesen. Nach Ende des Einlesens wird die Datei geschlossen und der erste Knoten als Kopie in den Speicher des N+1-ten geschrieben. 4. Die Ausgabetabelle wird von Altdaten befreit. Die in der Datenstruktur gespeicherten Daten werden in die Tabelle geschrieben. 5. Die Berechnung nach der 2. Brendt-schen Formel wird gestartet. ’ Einlesen der Daten Public Sub Lesen() Dim datei As String Dim nAnz As Integer Dim i As Integer ’ Dateiname ’ Anzahl der Knoten datei = Range("DNAME") nAnz = 0 ’ Dateinamen aus Tabelle holen ’ Konturknotenanzahl bestimmen ’ Datei öffnen E. Baeck K. LÖSUNG ZUR BRENDT’SCHEN FORMEL ReDim K(1 To 1) Open datei For Input As #1 Seite 109 ’ Datei zum Lesen öffnen ’ über alle Datensätze Do Until EOF(1) ’ Lesen bis zum Dateiende Input #1, K(1).y, K(1).z, K(1).t nAnz = nAnz + 1 ’ ... und Datensätze zählen, Loop ’ Datei schließen Close #1 ’ dann Datei wieder schließen ’ Konturknotendatenstruktur ReDim K(1 To nAnz + 1) ’ Jetzt Speicher für Knoten anlegen Open datei For Input As #1 ’ und Datei erneut öffnen ’ über alle Datensätze For i = 1 To nAnz ’ Input #1, K(i).y, K(i).z, Next K(nAnz + 1) = K(1) ’ ’ ’ Datei schließen Close #1 Einlesen und speichern aller Knotendaten K(i).t 1. Knoten als Knoten N+1 doppeln, da zyklisches Problem ’ Ausgaber der Daten in Tabelle Call Loeschen("KKTAB", 3) For i = 1 To nAnz + 1 Range("KKTAB")(i, 1) = K(i).y Range("KKTAB")(i, 2) = K(i).z Range("KKTAB")(i, 3) = K(i).t Next ’ Berechnung durchführen und Werte ausgeben Call Berechnung ’ Starten der Berechnung End Sub Das Löschen der Tabelle erfolgte mit folgendem Programm. Der erste Paramter ist die Bezeichnung des ersten Tabellenfeldes, d.h. des Tabellenfeldes der ersten Zeile und der ersten Spalte. Der zweite Parameter gibt an, wieviele Spalten gelöscht werden sollen, wenn in der ersten Spalte der betrachteten Teiltabelle kein Leertext gefunden wird. Der Vorgang des Löschens beginnt in der ersten Tabellenzeile und wird solange in einer nächsten Zeile fortgesetzt, bis in dieser ein Leertext gefunden wird. ’ Löschen eines Tabellenbereichs Sub Loeschen(z0 As String, nSpa As Integer) Dim iz As Integer 19.10.2011 Seite 110 Bauinformatik - Teil 1 - Übungsskript / 2011 Dim j As Integer iz = 1 Do While Range(z0)(iz, 1) <> "" For j = 1 To nSpa Range(z0)(iz, j) = "" Next Loop End Sub K.5 Hilfsfunktionen der Berechnung Um das Berechnungsprogramm übersichtlicher zu gestalten, werden allgemeine Rechenoperationen, wie die Bestimmung einer mittleren Dicke zwischen zwei Knoten, die Berechnung des Abstandes zweier Knoten und die Berechnung der Polygonfläche in Unterprogrammen ausgelagert. K.5.1 Berechnung der mittlerern Blechdicke Die Funktion berechnet die mittlere Dicke der Verbindung zwischen den Konturknoten i und i+1. ’ Gestimmt die Dicke Public Function GetDicke(i As Integer) As Double GetDicke = (K(i).t + K(i + 1).t) / 2 End Function K.5.2 Berechnung des Knotenabstandes Die Funktion berechnet den Abstand zwischen den Knoten i und i+1. ’ Gestimmt die Länge Public Function GetLaenge(i As Integer) As Double GetLaenge = Sqr((K(i).y - K(i + 1).y) ^ 2 + (K(i).z - K(i + 1).z) ^ 2) End Function E. Baeck K. LÖSUNG ZUR BRENDT’SCHEN FORMEL K.5.3 Seite 111 Berechnung der Polygonfläche Die Funktion berechnet den Flächeninhalt der durch die Konturknoten aufgespannten Fläche. Es wird vorausgesetzt, dass der 1. Konturknoten als n+1 -Knoten in der Knotenliste ergänzt wurde. ’ Gestimmt die Fläche eines Polygons Public Function GetFlaeche() As Double Dim i As Integer Dim A As Double A = 0 For i = 1 To UBound(K) - 1 ’ über alle Knoten A = A + K(i).y * K(i + 1).z - K(i).z * K(i + 1).y Next GetFlaeche = A / 2 End Function 19.10.2011 Seite 112 Bauinformatik - Teil 1 - Übungsskript / 2011 Literatur [1] H. Rubin, K.-J. Schneider Baustatik, Theorie I. und II. Ordnung Werner Verlag, 2002 [2] H. R. Schwarz Methode der finiten Elemente Teubner Studienbücher Mathematik, B.G. Teubner, Stuttgart 1984 [3] R. Sedgewick Algorithmen in C++ (auch für VBA-Programmierung als Vorlage zu empfehlen!) Addison-Wesley, 1992 [4] Peter Fröhlich (Hrsg.) Berechnungsbibliothek Bauwesen Vieweg & Sohn Verlagsgesellschaft mbH, Braunschweig/Wiesbaden, 1998 E. Baeck