Wiki: Mathe und Info

Unterrichtsmaterialien für Mathematik und Informatik

Benutzer-Werkzeuge

Webseiten-Werkzeuge


info:sek-ii:q3:komplexitaet:l1-primfaktoren

Laufzeitverhalten der Primfaktorzerlegung

Primzahlen
Primzahlen haben interessante mathematische Eigenschaften und spielen eine zentrale Rolle bei der Entwicklung kryptografischer Verfahren (z.B. RSA). Insbesondere nutzt man aus, dass eine Primfaktorzerlegung bei großen Ausgangszahlen nur mit sehr hohem Rechenaufwand möglich ist.
Primzahlen
Primzahlen sind natürliche Zahlen, die größer als 1 sind und nur durch 1 und sich selbst ohne Rest teilbar sind.


Beispiel: $$2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, ...$$

Eine der wichtigsten Eigenschaften von Primzahlen ist, dass sie als Bausteine der natürlichen Zahlen angesehen werden können.

Primfaktorzerlegung
Jede natürliche Zahl lässt sich als Produkt von Primzahlen schreiben. Diese Darstellung ist bis auf die Reihenfolge der Faktoren eindeutig.


Beispiel: Die Zahl 260 kann wie folgt mit Primzahlen aufgebaut werden:

$$260 = 2\cdot 2\cdot 5\cdot 13 = 2^2\cdot 5^1\cdot 13^1$$

Man nennt die Primzahlen, die in einer Produktdarstellung einer gegebenen Zahl vorkommen, auch Primfaktoren der Zahl.

Faktorisierungsproblem
Das Faktorisierungsproblem besteht darin, eine vorgegebene Zahl in ein Produkt aus Primfaktoren zu zerlegen.


Bei kleineren Zahlen kann man eine Primfaktorzerlegung oft direkt angeben. Bei größeren Zahlen sollte man systematisch vorgehen, um die Primfaktoren zu bestimmen. Bei noch größeren Zahlen ist es ratsam, die erforderlichen Berechnungen von einem Computer ausführen zu lassen - der kann das viel zuverlässiger und schneller.

Ein erster Algorithmus

Aufgabe 1
a) Bei kleineren Zahlen kann man eine Primfaktorzerlegung oft direkt angeben. Bestimme eine Primfaktorzerlegung von $n = 48$ und $n = 100$.


b) Bei größeren Zahlen sollte man systematisch vorgehen, um die Primfaktoren zu bestimmen. Bestimme eine Primfaktorzerlegung von $n = 221$ und $n = 585$.

c) Entwickle einen Algorithmus zur Primfaktorzerlegung. Beschreibe das Verfahren als Pseudocode.

d) Entwickle ein Programm zur Primfaktordarstellung mit Processing. Es bietet sich an, eine Funktion int[] primfaktoren(int n) zu erstellen, die die Liste der Primfaktoren zurückgibt.

Aufgabe 2
a) Teste die Funktion primfaktoren(n). Wie zeigt sich, dass die Ausgangszahl eine Primzahl ist?


b) Bestimme mit der Funktion primfaktoren(n) die Primfaktorzerlegung der beiden Zahlen $1000000000000000000L$ und $1000000000000000003L$ (das L am Ende muss sein, damit Java die Zahl als long erkennt!). Was stellst du fest? Stelle eine Vermutung auf, warum es hier zu einem unterschiedlichen Laufzeitverhalten kommt.

Messen der Laufzeit

Messen der Laufzeit

Das folgende Testprogramm zeigt, wie man in Processing die Laufzeit messen kann.

// Erste Messung
long time = System.nanoTime();
 
// Lange dauerndes Programm ausführen
machWasDasSehrLangeDauert();
 
// Zweite Messung
long delta = System.nanoTime() - time;
double seconds = delta / 100000000d;
 
println("Rechenzeit: ", seconds);
Aufgabe 3
Führe selbst auf diese Weise Laufzeitmessungen von primfaktoren(n) durch. Notiere dir die Laufzeit abhängig von der Eingabezahl.
Systematisches Testen
Um Gesetzmäßigkeiten herauszufinden, sollte man beim Testen systematisch vorgehen.


Zunächst ist es günstig, sich auf Zahlen eines bestimmten Typs zu beschränken. Der Worst Case der Primfaktorzerlegung tritt auf, wenn viele Probedivisionen durchgeführt werden müssen, z.B. wenn die zu verarbeitende Zahl $n$ eine Primzahl ist. Dann muss $n$ durch alle Zahlen von $2$ bis $\sqrt{n}$ dividiert werden.

Interessiert man sich für den Zusammenhang zwischen der Größe der Zahl $n$ und der Laufzeit, sollte man $n$ systematisch vergrößern. Wir werden im Folgenden $n$ immer (in etwa) um eine 10er-Potenz (d.h. eine Dezimalstelle) vergrößern. Als Testzahlen werden der Reihe nach die jeweils kleinsten Primzahlen genommen, die größer als die nächste 10er-Potenz sind:

$$11,101,1009,10007,100003,1000003,10000019,100000007,1000000007,10000000019,100000000003,1000000000039,...$$

Aufgabe 4
a) Lade dir die Vorlage unten herunter. Versuche, den Code nachzuvollziehen. Da Java's Datentyp long nur Zahlen bis 9223372036854775807 speichern kann, wurde für die Vorlage der Datentyp BigInteger gewählt.


b) Führe die Laufzeitmessungen durch. Entscheide selbst, wann du die Ausführung der Berechnungen abbrichst. Warum solltest du während der Messreihe keine anderen Programme starten und verwenden?

Gesetzmäßigkeiten herausfinden

Analyse der Messergebnisse

Folgende Messergebnisse erhält man, wenn man systematische Laufzeitmessungen durchführt. Beachte, dass die Messergebnisse vom benutzten Rechner abhängen. Deine Messergebnisse werden sich daher wohl von den hier gezeigten unterscheiden.

[11] -> 0.00043369 sec.
[101] -> 0.00124726 sec.
[1009] -> 0.00342708 sec.
[10007] -> 0.01014742 sec.
[100003] -> 0.02089646 sec.
[1000003] -> 0.02341614 sec.
[10000019] -> 0.02533699 sec.
[100000007] -> 0.0784865 sec.
[1000000007] -> 0.12939983 sec.
[10000000019] -> 0.24801863 sec.
[100000000003] -> 0.32550985 sec.
[1000000000039] -> 0.92951605 sec.
[10000000000037] -> 1.92971514 sec.
[100000000000031] -> 5.73045039 sec.
[1000000000000037] -> 17.88940701 sec.
[10000000000000061] -> 56.39213684 sec.
[100000000000000003] -> 175.94894516 sec.
[1000000000000000003] -> 555.15387059 sec.
[10000000000000000051] -> 5306.68616176 sec.
???
Aufgabe 5
Kannst du anhand der Zahlen bereits erste Zusammenhänge erkennen? Kannst du anhand der Zusammenhänge Prognosen erstellen, wie lange man wohl bis zum nächsten Ergebnis warten muss.
Gesetzmäßigkeiten beschreiben
Die Messergebnisse weisen (in etwa) folgende Regelmäßigkeit auf: Wenn man die Anzahl der Stellen der Ausgangszahl $n$ um $2$ erhöht, dann erhöht sich die Laufzeit um den Faktor $10$. Jede zusätzliche Stelle bei der Ausgangszahl führt also dazu, dass die Laufzeit mit dem Faktor $\sqrt{10}$ multipliziert wird.


Es handelt sich hier um ein exponentielles Wachstumsverhalten, das man mathematisch mit einer Exponentialfunktion beschreiben kann: Wenn $k$ die Anzahl der Stellen der Ausgangszahl $n$ angibt, dann erhält man eine Laufzeit vom Typ $L(k) = c\cdot\sqrt{10}^k$ mit einer (zunächst noch unbekannten) Konstanten $c$.

Rohdaten der Analyse
Primzahl $n$ Länge $k$ Laufzeit [Sek.]
11 2 0.0000020000
101 3 0.0000020000
1009 4 0.0000030000
10007 5 0.0000070000
100003 6 0.0000210000
10…03 7 0.0000720000
10…019 8 0.0002380000
10…07 9 0.0007480000
10…07 10 0.0023330000
10…019 11 0.0089420000
10…03 12 0.0287030000
10…039 13 0.0925700000
10…037 14 0.2831490000
10…031 15 0.8942920000
10…037 16 2.8316820000
10…061 17 9.2346320000
10…03 18 29.4374940000
10…03 19 91.8103500000
10…051 20 393.7519600000
Laufzeitanalyse in GeoGebra
Laufzeitanalyse in GeoGebra
Eine Regressionsanalyse (roter Graph) ergibt die Funktion $0.0000000426\cdot e^{1.1236\cdot k}$.


Überprüft man die theoretischen Überlegungen von vorhin mit der so berechneten Konstante $c=0.0000000426$, so ergibt sich die Funktion $0.0000000426\cdot \sqrt{10}^{k}$ (grauer Graph). Somit sind die theoretischen Überlegungen (zumindest für diesen Anwendungsfall und diesen Durchlauf) bestätigt.

Prognosen erstellen
Wie lange dauert es im ungünstigsten Fall, wenn man eine natürliche Zahl mit 100 Stellen in ihre Primfaktoren zerlegen möchte?


Wenn man das Laufzeitverhalten eines Algorithmus / Programms mit einer Gesetzmäßigkeit beschreiben kann, dann lässt sich diese Gesetzmäßigkeit benutzen, um Prognosen zu erstellen.

Beim vorliegenden Programm zur Primfaktorzerlegung benötigt man etwa 1 Sekunde, um eine 15-stellige Zahl im worst case zu faktorisieren. Wenn die Zahl 100 Stellen haben soll, kann man die worst-case-Laufzeit mit der o.g. Funktionsgleichung berechnen, also $0.0000000426\cdot \sqrt{10}^{100} = 4.26 \cdot 10^{42} $ Sekunden, was etwa $1.351\cdot 10^{35}$ Jahren entspricht…

Aufwandsabschätzungen und Komplexitätsbetrachtungen

Aufgabe 6

Lies Aufwandsabschätzungen und Komplexitätsbetrachtungen auf inf-schule.de. Beantworte danach die folgenden Fragen:

  1. Warum Aufwandsabschätzungen?
    • Was versteht man unter "Problemgröße"?
    • Was versteht man unter best/average/worst case?
    • Was ist eine Kostenfunktion?
    • Wann gelten Algorithmen als praktisch anwendbar?
  2. Warum Komplexitätsbetrachtungen?
    • Was versteht man unter Zeitkomplexität?
  3. Wie könnte man den Probedivisionsalgorithmus verbessern?
info/sek-ii/q3/komplexitaet/l1-primfaktoren.txt · Zuletzt geändert: 2022-11-27 21:26 von christian.weber