Einstieg in die Informatik mit Java Effizienz Gerd Bohlender Institut fur ¨ Angewandte und Numerische Mathematik

1 / 31

Gliederung

¨ zur Effizienz 1 Uberlegungen

2 Landau-Symbole

3 Eier im Korb

4 Zyklische Ziffern

2 / 31

Gliederung

¨ zur Effizienz 1 Uberlegungen

2 Landau-Symbole

3 Eier im Korb

4 Zyklische Ziffern

3 / 31

¨ Uberlegungen zur Effizienz

• Benotigte ¨ Rechenzeit • Ausnutzung der Performance des Computers • Beispiel Parallelrechner mit p Prozessoren:

Effizienz(p) =

Zeit(1) pZeit(p)

• Benotigter ¨ Speicher • Aufwand des Programmierers • ... • 2 Beispiele

4 / 31

Gliederung

¨ zur Effizienz 1 Uberlegungen

2 Landau-Symbole

3 Eier im Korb

4 Zyklische Ziffern

5 / 31

Asymptotischer Aufwand eines Algorithmus – Landau-Symbole

• Schreibweise O(g(n))

¨ Landau-Symbole (Edmund Landau, Gottingen, 1877-1938) • Die Funktion f (n) ist O(g(n)), fur ¨ n → ∞, genau wenn es

Konstanten n0 und M gibt mit |f (n)| < M · |g(n)| fur ¨ alle n > n0 • Dabei ist g(n) meist eine einfache Funktion, z.B.

O(n), O(n2 ), O(log n), ...

6 / 31

Landau-Symbole – Anwendung • Angaben zum Rechenaufwand eines Algorithmus

¨ (asymptotische Komplexitat) • Angaben zum Speicherbedarf eines Algorithmus

Beispiel n × n-Matrix (n Zeilen, n Spalten) • Speicherbedarf O(n2 ) • Rechenaufwand fur ¨ Addition O(n2 ) • Rechenaufwand fur ¨ Multiplikation O(n3 )

n 10 100 1000

O(n2 ) 100 10000 1000000

O(n3 ) 1000 1000000 1000000000 7 / 31

Landau-Symbole – Rechenregeln

• O(c · g(n)) = O(g(n)) fur ¨ eine Konstante c • O(g(n) + h(n)) = max(O(g(n), O(h(n)) • z.B. O(2n3 + 3n2 + 24n + 799) = O(n3 )

8 / 31

Landau-Symbole – Einsatz zum Vergleich von Algorithmen Beispiel: sortiere n Zahlen x0 , x1 , . . . , xn−1

n 2 4 8 ... 1000 106

Algorithmus 1 (Bubblesort) O(n2 ) 4 16 64

Algorithmus 2 (Quicksort) O(n log n) 2 8 24

106 1012

10000 20 · 106

• Algorithmus ist fur ¨ n = 106 etwa 100000 mal schneller. • 100000 ≈ 1 Tag / 1 Sekunde 9 / 31

Landau-Symbole – Vorsicht

• Aber Vorsicht! Alle Aussagen gelten nur asymptotisch fur ¨

n → ∞, also ab einem (unbekannten) n0 und mit einem (unbekannten) Faktor M. • Fur ¨ Algorithmus 1 durchaus ¨ ein kleines“ n konnte ” schneller sein als Algorithmus 2.

10 / 31

Gliederung

¨ zur Effizienz 1 Uberlegungen

2 Landau-Symbole

3 Eier im Korb

4 Zyklische Ziffern

11 / 31

Eier im Korb - Aus einem alten Rechenbuch ¨ den Korb voller Eier einer Marktfrau um. Die Ein Mann stoßt Eier gehen zu Bruch. Der Mann will den Schaden ersetzen und fragt wieviele Eier im Korb waren. Die Marktfrau antwortet: Die genaue Zahl weiß ich nicht. ” Aber wenn ich immer 2 Eier aus dem Korb genommen habe, dann blieb eines ubrig. ¨ Genauso, wenn ich immer 3, immer 4, immer 5 oder immer 6 Eier heraus genommen habe. Aber wenn ich immer 7 Eier heraus genommen habe, dann blieb keines ubrig.“ ¨ Wieviele Eier waren (mindestens) im Korb?

12 / 31

Eier im Korb - Erster Algorithmus

Teste alle Zahlen n = 1, 2, 3, ... • Beginne mit n = 1 • Prufe, ¨ ob die Zahl n bei Division durch 2, 3, 4, 5, 6 den

Rest 1 ergibt und ob n durch 7 ohne Rest teilbar ist. • Ist dies der Fall, dann brich ab und gib das Ergebnis aus.

¨ Andernfalls erhohe n um 1 und prufe ¨ nochmal.

13 / 31

Eier im Korb - Erstes Java-Programm

public class E i e r { public s t a t i c void main ( S t r i n g [ ] args ) { i n t i =0; do i ++; while ( i %2!=1 | | i %3!=1 | | i %4!=1 | | i %5!=1 | | i %6!=1 | | i %7!=0); System . o u t . p r i n t l n ( ” Es waren ” + i + ” E i e r im Korb . ” ) ; } }

14 / 31

Eier im Korb - Zweiter Algorithmus

Es kommen nur Zahlen in Frage, die bei Division durch 2, 3, 4, 5, 6 den Rest 1 ergeben. Mit etwas Mathematik stellt man fest: Es kommen nur Zahlen in Frage, die bei Division durch kgV(2, 3, 4, 5, 6) = 60 den Rest 1 ergeben. Also: Teste alle Zahlen n = 1, 61, 121... • Beginne mit n = 1 • Prufe, ¨ ob n durch 7 ohne Rest teilbar ist. • Ist dies der Fall, dann brich ab und gib das Ergebnis aus.

¨ Andernfalls erhohe n um 60 und prufe ¨ nochmal.

15 / 31

Eier im Korb - Zweites Java-Programm

public class E i e r 2 { public s t a t i c void main ( S t r i n g [ ] args ) { i n t i =1; do i += 6 0 ; while ( i %7 ! = 0 ) ; System . o u t . p r i n t l n ( ” Es waren ” + i + ” E i e r im Korb . ” ) ; } }

16 / 31

Vergleich der Effizienz

• Programm 2 braucht nur 1/60 der Rechenzeit von

Programm 1 • Beide Programm brauchen nur Bruchteile einer Sekunde • Rechenzeit spielt hier keine Rolle • Fazit: Die Arbeitszeit des Programmierers fur ¨ die

¨ mathematischen Uberlegungen ist verschwendet“ ” ¨ • Ubrigens ... es waren 301 Eier im Korb!

17 / 31

Gliederung

¨ zur Effizienz 1 Uberlegungen

2 Landau-Symbole

3 Eier im Korb

4 Zyklische Ziffern

18 / 31

Zyklische Ziffern - Das Problem

• Finde eine Zahl mit Endziffer 5 • Multipliziere sie mit 5 • Ist das Produkt gleich der ursprunglichen Zahl, wenn man ¨

die 5 am Ende streicht und dafur ¨ vorne anfugt? ¨ • Beispiel: 5 * abcd5 = 5abcd

(mit 4 Ziffern a, b, c, d) • Verallgemeinerung: ersetze 5 durch Faktor 2 bis 9

Quelle: Jacques Arsac, Computerdenkspiele selbst programmiert, Problem 3

19 / 31

Zyklische Ziffern - Erster Algorithmus

Teste alle Zahlen n = 1, 2, 3, ... • Beginne mit n = 1 • Prufe, ¨ ob die Zahl n die Bedingung Zyklische Ziffern“ erfullt ¨



• Ist dies der Fall, dann brich ab und gib das Ergebnis aus.

¨ Andernfalls erhohe n um 1 und prufe ¨ nochmal.

20 / 31

Zyklische Ziffern - Erstes Java-Programm

public class Z y k Z i f f 1 { public s t a t i c void main ( S t r i n g [ ] args ) { i n t i =0; do i ++; while ( i ∗5 ! = i / 1 0 + 5 0 0 0 0 ) ; / / b e i 4 Z i f f e r n abcd System . o u t . p r i n t l n ( ” Z y k l i s c h e Z i f f e r n : ” + i ) ; } }

21 / 31

Zyklische Ziffern - Probleme mit diesem Programm

• Unbekannt, ob 4 Stellen abcd notig ¨ sind oder mehr oder

weniger • Ggf. mussen alle Stellenzahlen durchprobiert werden ¨ • Reicht der Zahlbereich von int (9 Stellen) aus? • Reicht long (19 Stellen)? • Rechenzeit???

22 / 31

Zyklische Ziffern - Mathematische Idee Fuhre Ziffernvergleich bei 5 ∗ abcd5 = 5abcd durch, ¨ beginnend bei der niederwertigsten Ziffer. • 5 ∗ abcd5 = 5abcd fuhrt wegen 5 ∗ 5 = 25 zu d = 5 ¨

¨ • Es entsteht ein Ubertrag ¨ von 2, der im nachsten Schritt zu berucksichtigen ist ¨ • 5 ∗ abc55 = 5abc5 fuhrt wegen 5 ∗ 5 + 2 = 27 zu c = 7 ¨

¨ • Es entsteht ein Ubertrag von 2 • 5 ∗ ab755 = 5ab75 fuhrt wegen 5 ∗ 7 + 2 = 37 zu b = 7 ¨

¨ • Es entsteht ein Ubertrag von 3 • usw. (egal wie viele Stellen abcd vorliegen) • Der Algorithmus ist zu Ende, wenn • die berechnete Ziffer = 5 ist, und ¨ • der Ubertrag = 0 ist

23 / 31

Zyklische Ziffern - Zweiter Algorithmus

Verallgemeinerung: ersetze 5 durch beliebigen Faktor 2 bis 9 ¨ • Starte mit Ziffer = Faktor und Ubertrag =0 • Berechne das 2-stellige Produkt = Ziffer * Faktor +

¨ Ubertrag • Zerlege Produkt in die niederwertige Ziffer

¨ ¨ und den hoherwertigen Ubertrag • Wiederhole solange • die berechnete Ziffer nicht gleich dem Faktor ist, oder ¨ • der Ubertrag nicht 0 ist

24 / 31

Zyklische Ziffern - Zweites Programm import j a v a . u t i l . ∗ ; public class Z y k z i f f 5 { public s t a t i c void main ( S t r i n g [ ] args ) { Locale . s e t D e f a u l t ( Locale .US ) ; Scanner sc = new Scanner ( System . i n ) ; i n t Faktor , Z i f f e r , Uebertrag =0 , Produkt , S t e l l e n =0; System . o u t . p r i n t ( ” M i t welchem F a k t o r s o l l m u l t i p l i z i e r t werden ? ” ) ; F a k t o r = sc . n e x t I n t ( ) ; / / Faktor einlesen Z i f f e r = Faktor ; / / niederwertigste Z i f f e r = Faktor System . o u t . p r i n t l n ( ” Das Ergebnis l a u t e t ( r u e c k w a e r t s gelesen ! ) : ” ) ; do { System . o u t . p r i n t ( Z i f f e r ) ; / / a k t u e l l e Z i f f e r ausdrucken S t e l l e n ++; / / S t e l l e n z a h l b e i j e d e r Ausgabe erhoehen Produkt = Z i f f e r ∗ F a k t o r + Uebertrag ; / / neues Produkt , z w e i s t e l l i g Z i f f e r = Produkt % 1 0 ; / / neue Z i f f e r = n i e d e r s t e S t e l l e des Produkts Uebertrag = Produkt / 1 0 ; / / neuer Uebertrag = hoechste S t e l l e des Produk } / / wiederholen , wenn e i n e der beiden . . . while ( Z i f f e r ! = F a k t o r | | Uebertrag ! = 0 ) ; / / . . . Abbruch−Bedingungen v e r l e t z t i s t System . o u t . p r i n t l n ( ) ; System . o u t . p r i n t l n ( ” Es h a t ” + S t e l l e n + ” S t e l l e n ” ) ; } }

25 / 31

Zyklische Ziffern - Ergebnisse

c:\b\java>java Zykziff5 Mit welchem Faktor soll multipliziert werden ? 5 Das Ergebnis lautet (rueckwaerts gelesen !): 557783964376381959798442216035623618040201 Es hat 42 Stellen

26 / 31

Zyklische Ziffern - Ergebnisse Mit welchem Faktor soll multipliziert werden ? 2 248637498751362501 Es hat 18 Stellen Mit welchem Faktor soll multipliziert werden ? 3 3973142715569860268572844301 Es hat 28 Stellen Mit welchem Faktor soll multipliziert werden ? 4 465201 Es hat 6 Stellen Mit welchem Faktor soll multipliziert werden ? 6 6697760446811726754748050389833022395531882732452519496101 Es hat 58 Stellen Mit welchem Faktor soll multipliziert werden ? 7 7975048813263572944101 Es hat 22 Stellen Mit welchem Faktor soll multipliziert werden ? 8 8487228562101 Es hat 13 Stellen Mit welchem Faktor soll multipliziert werden ? 9 91742202834944046788980825779716505595321101 Es hat 44 Stellen

27 / 31

Zyklische Ziffern - Laufzeit des zweiten Algorithmus

• 42 Schleifendurchlaufe ¨ • etwa 10 Operationen pro Schleife • theoretisch etwa 10−7 Sekunden auf einem

handelsublichen PC ¨ • mit Java-Overhead (Interpretation, Startup)

deutlich unter 1 Sekunde

28 / 31

Zyklische Ziffern - Laufzeit des ersten Algorithmus

• Er benotigt ¨ ¨ 1042 Schleifendurchlaufe

= etwa 1043 Operationen • Schnellster Rechner zzt. (2007, Quelle: www.top500.org):

knapp 1015 Flops • Dieser braucht etwa 1028 Sekunden zur Losung ¨ • 1028 Sekunden = etwa 1020 Jahre

(1 Jahr = 365 ∗ 86400 Sekunden = etwa 3 ∗ 107 Sekunden) • ... aber das Universum existiert erst

etwa 1010 Jahre seit dem Urknall!

29 / 31

Zyklische Ziffern - Laufzeitvergleich der beiden Algorithmen

• Der erste Algorithmus braucht 1020 Jahre auf dem

schnellsten Rechner der Erde • Der zweite Algorithmus braucht einen Bruchteil einer

Sekunde auf einem handelsublichen PC ¨ • Fazit: Nachdenken uber mathematische Hintergrunde hat ¨ ¨

sich gelohnt

30 / 31

Zyklische Ziffern - Wann sind Computer schnell genug fur ¨ den ersten Algorithmus?

• Der erste Algorithmus braucht 1020 Jahre auf dem heute

schnellsten Rechner der Erde • Supercomputer wurden im letzten Jahrzehnt fast um den

Faktor 1000 schneller (Quelle: www.top500.org) • In 70 Jahren ware ¨ das (theoretisch!!!) ein Faktor 1021 • Im Jahre 2080 brauchte ¨ der schnellste Computer der Erde

noch 1 Monat (sehr theoretisch!!!)

31 / 31