Generierung von Zufallszahlen gemäß einer vorgegebenen diskreten Verteilung

Ähnliche Dokumente
Fallstudie: Simulation eines Geldautomaten

OLConnector Programmierung

Makro + VBA 2007 effektiv

Klausur SS 2014 EDV Anwendungen im Bauwesen. Name: Vorname: Matr.-Nr:

Algorithmen und ihre Programmierung

Klausur SS 2011 EDV Anwendungen im Bauwesen 2. Name: Vorname: Matr.-Nr:

Informationsverarbeitung im Bauwesen

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

Modul 122 VBA Scribt.docx

INFORMATIK TEIL: VBA. Infromatik WS 17/18 Teil: VBA. Allgemeines: - 4 Übungen á 3 Stunden

6 Technische Statistik und Wahrscheinlichkeitsrechnung

Arrays. Arrays werden verwendet, wenn viele Variablen benötigt werden. Der Vorteil in Arrays liegt darin, dass man nur eine Variable deklarieren muss

Programmieren mit Excel VBA Teil 2 Formulare als Benutzerschnittstellen

Informationsverarbeitung im Bauwesen

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA CustomViews in VBA nutzen HARALD NAHRSTEDT. Erstellt am

Zur drittletzten Zeile scrollen

17 VBA-Praxisbeispiel

Michaela Weiss 30. März Lerneinheit 3: VBA Teil 1: Eingabe/Ausgabe

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

Excel Funktionen durch eigene Funktionen erweitern.

Mit ParamArrays unter VBA kann man Prozeduren und Funktionen mit einer flexiblen Anzahl von Parametern bestücken Kontext

Universität Duisburg - Essen

DV-Organisation und Anwendungsentwicklung. 4. Klausur

Makro Programmierung User Interface (Entwicklungs- Umgebung) Grafische Werkzeugbox. GUI Form erstellen (UserForm)

Access [basics] Programmieren mit Arrays. Beispieldatenbank. Arrays. Eindimensionale Arrays. VBA-Grundlagen Programmieren mit Arrays

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

1 Excel Schulung Andreas Todt


Microsoft Access 2010 Bilder

Datenverarbeitung Klausur Gruppe A

Algorithmen und ihre Programmierung

Richtig Einsteigen: Excel 2007 mit VBA programmieren lernen Weber

Programmieren in Anwendungen

Anleitung zum Applet

1.) Behandlung von Laufzeitfehlern in Visual Basic

Algorithmen und ihre Programmierung -Teil 2-

STACK Mathematische Aufgaben mit ILIAS testen (Ein Frage-Typ im ILIAS-Objekt Test)

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Sequentielle Textdateien HARALD NAHRSTEDT. Erstellt am

Excel VBA Fehler im Programm

1. Auswählen der mit Blattschutz versehenen Datei

Access Programmierung. Ricardo Hernández García. 1. Ausgabe, November 2013 ACC2013P

12. ArcView-Anwendertreffen Workshop Programmierung in ArcGIS. Daniel Fuchs. Wo kann eigene Programmierung in ArcGIS verwendet werden?

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Objektbindungen und Verweise HARALD NAHRSTEDT. Erstellt am

VBA Programmierung Einführung

Klausur SS 2013 EDV Anwendungen im Bauwesen. Name: Vorname: Matr.-Nr:

4 Schleifen -= Entstanden unter Excel 2003 =-

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Einführung in die Programmierung für NF MI. Übung 04

Skriptum Bauinformatik SS 2013 (Vorlesung IV)

Verteilung des Korrelationskoeffizienten r. für zwei unabhängige normalverteilte Merkmale. Studie

Programmieren in Anwendungen

Inhalt. Dokument Beschreibung. Bentley Technical Support ProStructures.Net - Zusatzprogrammierung Visual Basic Express PST_Bearbeitung_Dialog

Variablen und Konstanten

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Namen in VBA nutzen HARALD NAHRSTEDT. Erstellt am

Überschrift/Caption. Eigenschaftenfenster

Microsoft Visio 2007-Programmierung

Werte zu Kombinationsfeldern hinzufügen

1 Visual Basic for Application mit Excel (VBA)

Vorbemerkungen. Die Programmieroberfläche des ClassPad

Verteilte Datenbanken

Einführung in die Programmierung mit VBA

White Paper Wählen-Buttons in Excel

Einführung in die Informatik - Teil 6a -

Funktionen in JavaScript

C++ - Objektorientierte Programmierung Konstruktoren und Destruktoren

Integration des VBA-Codes in Excel-Tabellen, Zugriff auf Datenbanken. Bernd Blümel

Access-Benutzeroberfläche

Access 2010 Programmierung Import und Export nach Excel

Visual Basic Express Fehlerermittlung

int i=1; //Integerzahl i anlegen und mit 1 initialisieren float wert; //Floatzahl deklarieren scanf( %f,&wert); //Wert über Tastatur eingeben

Seminar Finanzmathematik

15.4 Mit dem Printer -Objekt drucken

Access 2003 Programmierung mit Visual Basic

Felder (1) Felder (Arrays) speichern viele Datenelemente des gleichen Typs. Auf einzelne Elemente kann über einen Index zugegriffen werden

Access [basics] Aktionsabfragen per VBA ausführen. Beispieldatenbank. Aktionsabfragen. Die Execute-Methode. Datenzugriff per VBA

Visual Basic Basisbefehle Hinweis: Der Text in eckigen Klammern [ ] ist variabel, z.b. [var] => 5.3. Eckige Klammern sind stets wegzulassen!

Unpaarige Anfü hrüngszeichen ünd Klammern interaktiv korrigieren

Variablen und Datentypen

Access 2010 Programmierung Schleifen

Einführung in die Programmierung für NF MI. Übung 07

Objekte haben eine eigene Notation, also Schreibweise, beim Aufruf:

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Filter in VBA nutzen HARALD NAHRSTEDT. Erstellt am

Bilderverwaltung mit Access

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

Klassen und Objekte. Klassen sind Vorlagen für Objekte. Objekte haben. Attribute. Konstruktoren. Methoden. Merkblatt

Seminar Finanzmathematik

VBA mit Office 97 lernen

Code des Objektes frmdatenvisualisierung

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Kommentare mit VBA verwalten HARALD NAHRSTEDT. Erstellt am

10 Berechnungen aus der Elektrotechnik

Die Klasse Collection (gb) implementiert eine Hash-Tabelle, deren Elemente aus einem Wert-Schlüssel-Paar

Eine Seite formatieren. Folien formatieren Arbeitsbereich Ausführen. Folien auswählen. Folien einfügen. Autopilot. Folienübergänge und Animationen

Einstieg in die Programmierung mit Visual Basic.NET

Excel + VBA. Ergänzungen. Kapitel 1 Einführung in VBA Balloons in VBA nutzen HARALD NAHRSTEDT. Erstellt am

15 Fehler finden und behandeln

Funktionen in JavaScript

Visual Basic / EXCEL / Makroprogrammierung Unterrichtsreihe von Herrn Selbach

Klassen. 3.1 Was Sie in diesem Kapitel erwartet. 3.2 Allgemeines

MiniPPS - Systembeschreibung

Transkript:

Generierung von Zufallszahlen gemäß einer vorgegebenen diskreten Verteilung Die folgende Fallstudie eignet sich sehr gut zur Einarbeitung in die objektorientierte Programmierung. Es wird zunächst eine Klasse beschrieben, welche diskrete Zufallszahlen generiert. Danach wird gezeigt, wie man diesen Zufallszahlengenerator von einem Formular aus benutzen kann. Zufallszahlen werden häufig für Simulationsanwendungen gebraucht. Beispiel: Simulation eines Geldautomaten zur Optimierung der Füllung und der Auszahlungsstrategie. Man führt hierzu nacheinander eine größere Zahl fiktiver Abhebungen an dem gedachten Automaten durch und protokolliert, wie sich diese Abhebungen auf den Geldbestand und die Zahlungsfähigkeit des Automaten auswirken. Die Abhebungsbeträge werden mit Hilfe eines Zufallszahlengenerators gefunden. Natürlich sollen die generierten Abhebungsbeträge der Verteilung der tatsächlichen Abhebungen entsprechen. Belaufen sich z.b. in der Realität 50% der Abhebungen auf einen Betrag von 300, so sollen auch annähernd 50% der generierten Abhebungen diesem Betrag entsprechen. Man muss also dem Generator eine Häufigkeits- bzw. Wahrscheinlichkeitsverteilung der möglichen Beträge vorgeben können. Die ersten beiden Spalten der unten stehenden Tabelle zeigen, wie eine solche Verteilungsvorgabe aussehen kann. Die erst Spalte enthält die möglichen Werte, die zweite deren relative Häufigkeit bzw. Wahrscheinlichkeit in Prozent. Diese ersten beiden Spalten repräsentieren die sogenannte Wahrscheinlichkeitsfunktion. Die dritte Spalte enthält die kumulierten Wahrscheinlichkeiten, repräsentiert also mit der ersten Spalte zusammen die Verteilungsfunktion ( Summenkurve ). Die Spalten vier und fünf sind lediglich Umformungen der Spalten zwei und drei. Die Prozentangaben sind darin durch Anteilsangaben im Bereich [0, 1] ersetzt. Dies ist für die weitere Argumentation bequemer. Das folgende Bild zeigt die Graphen der Wahrscheinlichkeits- (links) und der Verteilungsfunktion (rechts).

Wie können wir Zufallszahlen generieren, die der dargestellten Verteilung entsprechen? In VBA haben wir, wie in den meisten Programmierumgebungen, nur einen Standard-Zufallszahlengenerator zur Verfügung, welcher gleichverteilte kontinuierliche Zufallszahlen im Bereich [0, 1[ erzeugt. Der diesbezügliche Befehl heißt Rnd (für random). Mit den folgenden Anweisungen können wir einer Variablen eine solche Standard-Zufallszahl zuweisen: Dim r As Double r = Rnd Das folgende Bild veranschaulicht das Prinzip, mit dem wir gleichverteilte kontinuierliche Zufallszahlen im Bereich [0, 1[ in diskrete Zufallszahlen mit der gewünschten Verteilung verwandeln können. Wir teilen hierfür den Wertebereich [0, 1[ der Standard-Zufallszahl in Teilbereiche auf, welche den Wahrscheinlichkeiten der Werte der gewünschten Verteilung entsprechen. Dabei beginnen wir mit dem kleinsten Wert. Dieser ist hier 50, seine Wahrscheinlichkeit beträgt 0,1 bzw. 10%. Die übrigen Werte werden in derselben Weise angefügt. Das so erzeugte Raster ist das Vehikel zur Umwandlung in die diskreten Werte. Generieren wir eine größere Menge von Standard-Zufallszahlen, so werden sich rund 10 % davon zwischen 0 und 0,1 befinden, also im Bereich des Werts 50, weitere 20% im Bereich des Werts 100, weitere 10% im Bereich des Werts 200 und so fort. Wenn wir also jeder Standard-Zufallszahl den diskreten Wert zuordnen, der dem Bereich entspricht, in den sie fällt, so erhalten wir damit Zufallszahlen der gewünschten diskreten Verteilung. Hierzu ein Beispiel: Eine mit Rnd erzeugte Standard-Zufallszahl sei 0.34592. Da dieser Wert sich im Bereich [0.3, 0.4[ des diskreten Werts 200 befindet, leiten wir davon die Zahl 200 ab. Die Berechnung dieses Umformungsraster macht keinen großen Aufwand, denn es ergibt sich aus den Ordinatenwerten der oben dargestellten Verteilungsfunktion. Diese bilden die Grenzen der Teilbereiche, die wir als Basis für die Umwandlung brauchen. Zur Verdeutlichung ist im folgenden Bild noch einmal die Verteilungsfunktion abgebildet, nun aber mit eingezeichneten Bereichsgrenzen.

Die Klasse DiscrDistGenerator (Zufallsgenerator) Die Klasse beginnt mit der Deklaration einer Instanzenvariablen s. Sie soll, in tabellarischer Form, die Verteilungsfunktion aufnehmen, welche der Generierung der Zufallszahlen zugrunde gelegt wird (s. oben). Es folgen dann drei Methoden; davon sind die ersten beiden die wichtigsten. Die Methode setdist nimmt ein Array entgegen, das die Wahrscheinlichkeitsfunktion der gewünschten Verteilung, also die möglichen Werte und ihre Wahrscheinlichkeiten, in tabellarischer Form enthält. Die Wahrscheinlichkeiten sind darin in % ausgedrückt. In setdist wird aus dieser Wahrscheinlichkeitsfunktion die Verteilungsfunktion abgeleitet und in der Instanzenvariablen s abgelegt. Methode rdist erzeugt einen einzigen Zufallswert gemäß der in s enthaltenen Verteilung auf der Basis einer gleichverteilten Standardzufallszahl runi, welche als Parameter übergeben wird. Wie oben ausgeführt, muss hierfür der Teilbereich innerhalb des Gesamtbereichs [0, 1[ identifiziert werden, in den runi fällt. Man könnte runi auch direkt innerhalb der Methode mit dem Befehl Rnd erzeugen, jedoch eröffnet die gewählte Lösung mit der Parameterübergabe die Möglichkeit, beliebige Zufallsgeneratoren zur Erzeugung von runi einzusetzen. Die Methode nvalues dient lediglich der Bequemlichkeit der Benutzer der Klasse. Sie erzeugt ein Array mit einer vorgegebenen Anzahl von Zufallszahlen. Hierfür wird die Methode rdist zur Erzeugung der einzelnen Zahlen aufgerufen. Option Explicit Private s() As Double 'Summenkurve (Verteilungsfunktion) 'aus der Verteilung v die Summenkurve s ableiten Public Sub setdist(byref v() As Double) Dim i As Integer ReDim s(1 To UBound(v, 1), 1 To 2) s(1, 1) = v(1, 1) s(1, 2) = v(1, 2) / 100 For i = 2 To UBound(s, 1) s(i, 1) = v(i, 1)

s(i, 2) = s(i - 1, 2) + v(i, 2) / 100 End Sub 'aus der gleichverteilten Zufallszahl runi einen Zufallswert ableiten Public Function rdist(byval runi As Double) As Double Dim i As Integer rdist = s(1, 1) For i = 2 To UBound(s, 1) If runi >= s(i - 1, 2) And runi < s(i, 2) Then rdist = s(i, 1) Exit For End If End Function 'ein Array mit n Zufallswerten generieren Public Function nvalues(byval n As Integer) As Double() Dim v() As Double ReDim v(1 To n, 1 To 1) Dim i As Integer For i = 1 To n v(i, 1) = rdist(rnd) nvalues = v End Function Eine Beispielanwendung, die den Zufallszahlengenerator verwendet In der folgenden Anwendung wird ein kleines Formular benutzt, um eine bestimmte, vom Benutzer vorzugebende Anzahl von Zufallszahlen zu erzeugen und auf einem Arbeitsblatt auszugeben (s. folgendes Bild). Die Wahrscheinlichkeitsfunktion der gewünschten Verteilung, bestehend aus den möglichen Werten und ihren in Prozent ausgedrückten Wahrscheinlichkeiten, muss vorher in tabellarischer Form eingegeben worden sein. Das Formular sollte mit Hilfe einer Prozedur in nichtmodaler Form gestartet werden. Nach dem Öffnen des Formulars gibt der Benutzer den Bereich des Arbeitsblatts ein, auf dem sich die Wahrscheinlichkeitsfunktion befindet. Zum Einlesen wird ein RefEdit-Steuerelement benutzt. Wurde bereits vor dem Starten der Maske dieser Bereich markiert, so ist das Steuerelement nach dem Start bereits mit diesem Bereich gefüllt. Die Anzahl der Zufallszahlen wird vom Benutzer mit Hilfe eines Auswahlfelds (ComboBox) festgelegt. Zur Auswahl stehen die Werte 10, 50, 100 und 1000. Danach wird die Erzeugung der Zahlen durch Anklicken der Schaltfläche <Zufallswerte generieren> gestartet. Fehler bei der Eingabe können lediglich beim RefEdit-Steuerelement vorkommen. Falls dieses Feld keine verwertbare Bereichsangabe enthält, wird eine entsprechende Fehlermeldung in einer MsgBox ausgegeben. Der Benutzer hat danach die Möglichkeit, seine Eingaben zu korrigieren.

Wir betrachten nun die Formularklasse ZZGeneratorForm. Die Instanzenvariable gen der oben beschriebenen Klasse DiscrDistGenerator wird innerhalb der Methode UserForm_Initialize mit einem Objekt dieser Klasse besetzt und steht danach der Methode GenerierenBtn_Click zur Verfügung. Diese leistet die Hauptarbeit, indem sie zunächst den im RefEdit-Steuerelement genannten Bereich liest und mit Hilfe der Hilfsfunktion RangeToDoubleMatrix in ein Array v umwandelt. Dieses Array wird dann dem Generator-Objekt übergeben, so dass dieses die in v enthaltene Verteilungsfunktion bei der Erzeugung der Zufallszahlen berücksichtigen kann. Anschließend werden die Zufallszahlen mit Hilfe der Methode nvalues vom Generator abgerufen und in das Arbeitsblatt eingestellt. Option Explicit Private gen As DiscrDistGenerator 'Aktionen beim Öffnen des Formulars Private Sub UserForm_Initialize() Set gen = New DiscrDistGenerator Me.AnzahlCBx.AddItem ("10") Me.AnzahlCBx.AddItem ("50") Me.AnzahlCBx.AddItem ("100") Me.AnzahlCBx.AddItem ("1000") Me.AnzahlCBx.Value = "50" Me.DistrREd.Text = ActiveWindow.RangeSelection.Address End Sub 'Aktionen nach Anklicken des Buttons <Generieren> Private Sub GenerierenBtn_Click() Dim rng As Range 'für die Verteilung Dim v() As Double 'für die Verteilung Dim z() As Double Dim i As Integer, n As Integer

'dem Generator die Verteilung übergeben On Error GoTo errorhandler Set rng = Range(Me.DistrREd.Text) v = RangeToDoubleMatrix(rng) gen.setdist v 'die Zufallswerte abrufen und ausgeben n = CInt(Me.AnzahlCBx.Text) z = gen.nvalues(n) Worksheets("Tabelle1").Range("E:E").Clear Worksheets("Tabelle1").Range("E2:E" & (n + 1)) = z Exit Sub errorhandler: MsgBox "Bitte den Bereich mit der Verteilung eingeben" Me.DistrREd.SetFocus End Sub 'Umwandlung eines Range in ein 2-dimensionales Array Public Function RangeToDoubleMatrix(ByVal rng As Range) As Double() Dim m() As Double Dim i As Integer, j As Integer ReDim m(1 To rng.cells.rows.count, 1 To rng.cells.columns.count) For i = 1 To UBound(m, 1) For j = 1 To UBound(m, 2) m(i, j) = CDbl(rng.Cells(i, j).value) Next j RangeToDoubleMatrix = m End Function Beachten Sie die Validierung der Bereichseingabe in das Steuerelement DistrREd. Eingaben dieser Art sind sehr schwer zu überprüfen. Man kann sich in solchen Fällen behelfen, indem man die Anweisung On Error GoTo vor die fehlerträchtigen Anweisungen setzt. Tritt dann tatsächlich ein Fehler auf, so wird die Marke angesprungen, welche nach dem GoTo genannt ist, hier also errorhandler. Dort erfolgt dann die Fehlerbehandlung.