Praktische Informatik I – Der Imperative Kern

Werbung
Praktische Informatik I – Der Imperative Kern
Mathematiknachhilfe
Prof. Dr. Stefan Edelkamp
Institut für Künstliche Intelligenz
Technologie-Zentrum für Informatik und Informationstechnik (TZI)
Am Fallturm 1, 28359 Bremen
+49-(0)421-218-64007
www.tzi.de/~edelkamp
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
1 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
2 / 18
In dieser Unterrichtseinheit soll der Nutzen der Rekursion für die
Bewältigung von praktisch relevanten Aufgabenstellungen mit
informatischen Mitteln deutlich werden.
Ausgehend von der Sekundarstufen-Mathematik wird das schnelle
Auswählen und Sortieren von Zahlen in Sequenzen besprochen.
Sie lernen
das Heron-Verfahren zur Quadratwurzelberechnung,
den Euklidische Algorithmus zur Bestimmung des größten
gemeinsamen Teiler,
das Pascal-Dreieck für die allgemeine Binomische Formel,
ein Verfahren zur eindeutigen Primfaktorzerlegung, sowie
das Gauß’sche Eliminationsverfahren zur Lösung von linearen
Gleichungssystemen
kennen
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
3 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
4 / 18
Heron-Verfahren
Programm 1 berechnet die (abgerundete) Quadratwurzel
Wir nehmen
ein Rechteck, bei dem die eine Kante Länge a hat, für das
√
man a sucht. Die zweite Kantenlänge ist 1. Das Verfahren nähert
sich iterativ einem Quadrat mit derselben Fläche an.
Das Verfahren fußt auf dem Banach’schen Fixpunktsatz
Programm 1: Iterative Wurzelberechnung.
public class Quiz
{
public int method(int i)
{
int a = i;
int b = 1;
while (a − b > 1) {
a = (a + b) / 2;
b = i / a;
}
return (a + b) / 2;
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
5 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
6 / 18
Der Euklidische Algorithmus
Die rekursive Berechnung des größten gemeinsamen Teilers (engl.
greatest common divisor) funktioniert wie folgt:
Wenn a mod b = 0 gilt, dann ist gcd(a, b) = b, sonst ist
ggT (a, b) = gcd(b, a mod b).
Invarianz Zweite Zahl ist kleiner als die erste Zahl
mod Rest bei der ganzzahligen Division, wobei der Rest der Division
mit Rest a mod b in Java durch a % b dargestellt wird.
Der Euklid’sche Algorithmus ist ein Paradebeispiel für ein effizientes
rekursives Verfahren: In jedem zweiten Schritt wird eine Eingabezahl
mindestens halbiert.
Das kleinste gemeinsame Vielfache (kgV) (engl. least common
multiplier) von a und b ergibt sich dann aus dem Produkt ab der
beiden Zahlen, geteilt durch ihren größten gemeinsamen Teiler.
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
7 / 18
Bruchrechnen
Das Programm 2 berechnet die Summe von zwei Brüchen inklusive
dem Erweitern der Brüche auf den Hauptnenner, sowie dem
automatischen Kürzen des Resultats.
Programm 2: Bruchrechnen mit Kürzen.
public class Fractional
{
public int gcd(int a, int b) {
return a == 0 ? b : gcd(b%a,a);
}
public int lcm(int a, int b) {
return a∗b / gcd(a,b);
}
public void compute(int a, int b, int c, int d) {
System.out.println("(a/b)−>("+(a/gcd(a,b))+"/"+(b/gcd(a,b))+")");
System.out.println("(c/d)−>("+(c/gcd(c,d))+"/"+(d/gcd(c,d))+")");
int k = lcm(b,d);
int s = a∗k/b + c∗k/d;
System.out.println("sum = ("+(s/gcd(s,k))+"/"+(k/gcd(s,k))+")");
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
8 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
9 / 18
Binomische Formel
n
k
n!
ist wichtig u.a. für die
= k !(n−k
!)
P
n
n k n−k
n
Darstellung von (a + b) = k =0 k a b
.
Der Binomialkoeffizient
Im Lotto ist ein Sechser bekanntlicherweise
mit einer
Wahrscheinlichkeit von 1/ 49
zu
finden.
6
Es ist nicht schwer, eine rekursive Beschreibung der Funktion
n(n − 1)!
n
n
n!
=
= c(n − 1, k − 1)
c(n, k ) =
=
(n − k )! · k !
k (n − k )!(k − 1)!
k
k
mit c(n, 0) = 1 herzuleiten.
Mit dem Programm 3
wird ein Pascal-Dreieck ausgegeben; es gibt in
Zeile n die Werte kn für alle k = 0, . . . , n dar.
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
10 / 18
Programm 3: Die rekursive Berechnung des Pascal’schen Dreiecks.
public class Binomial
{
private int choose(int n, int k) {
return (k == 0) ? 1 : (n ∗ choose(n−1,k−1)) / k;
}
public void triangle(int m) {
int n,k;
for (n=0;n<m;n++) {
for (k=0;k<=n;k++) {
System.out.print("("+m+","+k+")="+choose(n,k));
}
System.out.println();
}
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
11 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
12 / 18
Eindeutige Zerlegung in Primteiler
Die Zerlegung einer Zahl in ihre Primfaktoren nicht nur für die
Berechnung des ggTs und des kgVs wichtig: Sie ist (bei Sortierung)
eine eindeutige Darstellung.
Programm 4 ist eine rekursive Beschreibung, die nach und nach alle
Primfaktoren einer Zahl abspaltet.
Programm 4: Die rekursive Berechnung der Primfaktorzerlegung.
public class PrimeFactor
{
public void factor(int n) { // prime factorization of n
int i=2; // start with first prime factor
while((i<n) && (n%i != 0)) i++; // find next factor
System.out.println(i); // print found factor
if (i < n) factor(n/i); // call with reduced term
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
13 / 18
Outline
1
Unter- und Oberstufenmathematik
2
Quadratwurzel
3
Erweitern und Kürzen
4
Pascals Dreieck
5
Primfaktorzerlegung
6
Gauß-Elimination
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
14 / 18
Lösung von Gleichungssystemen
Das Gauß’sche Eliminationsverfahren zur Lösung von linearen
Gleichungssystemen Ax = b bei gegebener eindeutiger Lösbarkeit ist
nützlich . . .
. . . wenn auch numerisch nicht unbedingt stabil: Hier bietet sich die
exakte Berechnung der Lösung über die Menge der Bruchzahlen an.
Das Programm 5-6 geht grob wie folgt vor: Es bringt die Gleichungen
in Standardform und stellt die Koeffizientenmatrix auf.
Startpunkt ist i = 1.
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
15 / 18
Das Verfahren
1
Falls in der i-ten Zeile die Zahl in der i-ten Spalte 0 ist, wird diese
Zeile mit einer Zeile unterhalb ausgetauscht, bei der in der i-ten
Spalte eine Zahl steht. Falls keine solche Zeile existiert, ist das
Gleichungssystem nicht eindeutig oder auch gar nicht lösbar.
Danach wird die i-te Zeile durch die Zahl, in ihrer i-ten Spalte
geteilt. Das Diagonalelement wird dadurch 1.
2
Nun wird zu allen anderen Zeilen j mit j 6= i ein geeignetes
Vielfaches der Zeile i subtrahuiert, so daß die Zahl in der i-ten
Spalte der j-ten Zeile 0 wird. Danach darf in der i-ten Spalte nur
noch in der i-ten Zeile eine 1 stehen, sonst stehen nur noch
Nullen in dieser Spalte.
3
Falls i < n, wird i um eins erhöht und gehe zurück zu Schritt 1.
Die Lösung steht in der letzten Spalte.
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
16 / 18
Programm 5: Ein Löser für lineare Gleichungssysteme.
public class Gauss
{
static final int DIM = 4;
double M[][] = {
{1.0, 2.0, −1.0, −2.0}, {1.0, 3.0, −1.0, −2.0},{2.0, 1.0, 1.0, 1.0}, {3.0, 1.0, 2.0, 1.0}};
double V[] = {−6.0, −4.0, 11.0, 15.0};
double S[] = new double[DIM];
/∗∗
∗ Constructor for objects of class Gauss
∗/
public Gauss() {
if (solve(M, V)) {
for (int k = DIM−1; k>=0; k−−) {
S[k] = V[k];
for (int i=(k+1); i<DIM; i++) S[k] −= (M[k][i]∗S[i]);
S[k] = S[k] / M[k][k];
}
System.out.println("Solution:");
for (int i=0; i<DIM; i++)
System.out.print(" " + S[i]);
System.out.println();
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
17 / 18
Programm 6: Ein Löser für lineare Gleichungssysteme.
public boolean solve(double M[][], double V[]) {
for (int k=0; k<DIM−1; k++) {
double max = M[k][k] > 0 ? M[k][k] : −M[k][k];
int m = k;
for (int i=k+1; i<DIM; i++) {
double abs = M[i][k] > 0 ? M[i][k] : −M[i][k];
if (max < abs) { max = M[i][k]; m = i; }
}
if (m != k) {
for (int i=k; i<DIM; i++) { double t = M[k][i]; M[k][i] = M[m][i]; M[m][i] = t; }
double t = V[k]; V[k] = V[m]; V[m] = t;
}
if(M[k][k] == 0) return false;
for (int j=(k+1); j<DIM; j++) {
double f = − M[j][k] / M[k][k];
for (int i=k; i<DIM; i++) M[j][i] = M[j][i] + f∗M[k][i];
V[j] = V[j] + f∗V[k];
}
}
return true;
}
}
Stefan Edelkamp (IAI)
PI 1 – Imperativer Kern
October 9, 2013
18 / 18
Herunterladen