Zufallszahlen - Institut für Pervasive Computing

Transcrição

Zufallszahlen - Institut für Pervasive Computing
Institut für Pervasive Computing
Johannes Kepler Universität Linz
Übung 8
Übungen zu Algorithmen und Datenstrukturen 1
Übungen zu Praktische Informatik 1
SS 2012
Letzter Abgabetermin: Mi. 20.06.2012, 23:59 Uhr
Abgabe via Internet: www.pervasive.jku.at/Teaching/
Zufallszahlen
1. Käselaib
14 Punkte
Ein großer Käselaib wird einmal horizontal durchgeschnitten und
vertikal halbiert (siehe Abbildung 1). Betrachtet man nun einen
Teil des Käselaibs an seiner horizontalen Schnittfläche, erkennt
man eine halbkreisförmige Fläche, die in Abbildung 2 ersichtlich
ist.
Man sieht, dass der Käse mehrere Löcher an verschiedenen
Stellen hat, die sowohl überlappen, als auch an der anderen
Schnittkante durchgeschnitten worden sein können.
Abbildung 1: Schnittlinien
Gesucht ist nun ein Algorithmus in Jana, der den
Flächeninhalt der Schnittfläche (abzüglich) der Löcher
näherungsweise berechnet.
Es stehen Ihnen folgende Daten zur Verfügung:
• float rCheese
// Radius des Käselaibs
• float holesX[n]
// x-Koordinaten der Löcher
• float holesY[n]
// y-Koordinaten der Löcher
• float holesR[n]
// Radien der Löcher
• int n
// Anzahl der Löcher
• int numPoints
// Anzahl der Zufallspunkte
Der Mittelpunkt der halbkreisförmigen Schnittfläche hat die
Koordinaten (0, rCheese), die linke untere Ecke befindet
sich im Ursprung des Koordinatensystems.
Sie dürfen die Funktion float fRand() verwenden, die eine
Zufallszahl im Intervall [0, 1[ generiert.
Abbildung 2: Schnittfläche
Verwenden Sie für die Flächenberechnung den Monte-Carlo-Algorithmus: es werden zufällig
Punkte erzeugt, die sich entweder außerhalb, im Käse oder in einem der Löcher befinden. Aus
dem Verhältnis der Zufallspunkte die „im Käse“ beziehungsweise außerhalb (oder in einem
Loch) gelandet sind, lässt sich die gesuchte Querschnittsfläche näherungsweise berechnen.
Der Algorithmus soll folgendermaßen aufgerufen werden können:
float approxCheeseArea(↓rCheese ↓holesX ↓holesY ↓holesR ↓n ↓numPoints)
Hinweise:
• Überlegen Sie, in welchem Intervall Sie Zufallszahlen erzeugen müssen.
• Sie dürfen zur Lösung der Aufgabe keine Kreisfläche mathematisch berechnen!
2. Lotto 6 aus 45
4+6 Punkte
Ein Programmieranfänger schreibt einen Algorithmus für das zufällige Generieren eines LottoQuicktipps, bei dem aus den Zahlen 1-45 sechs verschiedene Zahlen gezogen werden. Dieser
sieht folgendermaßen aus:
int[] generateNumbers() {
int numbers[1:6]
for (int i = 1..6) {
boolean newNumber = false
int random = smallRand(↓45) + 1
while (!newNumber) {
newNumber = true
for (int j = 1..i-1) {
if (numbers[j] == random) {
newNumber = false
random = random + 1
if (random == 46) {
random = 1
}
}
}
}
numbers[i] = random
}
return numbers
}
a) Beurteilung des vorliegenden Algorithmus
Was sagen Sie zu diesem Ansatz? Analysieren Sie den Algorithmus, identifizieren Sie
mögliche Fehlerstellen und beschreiben Sie, warum er für eine „statistisch korrekte“
Generierung eines Lotto-Quicktipps ungeeignet ist.
b) Entwurf eines Algorithmus
Entwerfen Sie anschließend einen etwas allgemeineren Algorithmus, der eine obere und
eine untere Grenze von möglichen Lotteriezahlen entgegennimmt und eine gegebene
Anzahl von unterschiedlichen Zufallszahlen zurückliefert:
int[] generateNumbers(↓int low ↓int high ↓int num)
// low ist die Untergrenze der Zufallszahlen im Intervall [low, high]
// high ist die Obergrenze der Zufallszahlen im Intervall [low, high]
// num ist die Anzahl der zu generierenden Zufallszahlen aus [low, high]
Sie können dazu die Funktion int smallRand(↓int n) voraussetzen, die gleichverteilte
ganze Zufallszahlen aus dem Intervall [0, n-1] liefert. Der Rückgabewert der Funktion
soll ein Integer-Array sein, das mit den entsprechend erzeugten Zufallszahlen gefüllt
ist.
Achten Sie insbesondere darauf, dass alle möglichen Zahlenkombinationen mit gleicher
Wahrscheinlichkeit erzeugt werden.