Lösung Serie 3

Werbung
U NIVERSIT ÄT B ERN
I NFORMATIK
VORLESUNG
EI
T YP
UL
B LATT
3 (1/3)
AUSGABE
HS 08
Lösungsvorschlag Serie 3 – Analyse von Algorithmen
1. (a) Aussage: Ein Grossteil der heute eingesetzten Software ist verifiziert und deshalb korrekt.
Diese Aussage ist falsch.
Nur ein geringer Anteil der heute verwendeten Software wird formal verifiziert.
D.h. von einem Grossteil der eingesetzten Software ist nicht bewiesen, dass sie
korrekt ist.
(b) Aussage: Dank Tests werden alle in einer Software vorhandenen Fehler identifiziert.
Diese Aussage ist falsch.
Tests werden entworfen, um das Vorhandensein von Fehlern in ganz spezifischen
Konfigurationen nachzuweisen. Tests beweisen jedoch nicht, dass ein System
keine weiteren (versteckten) Fehler mehr hat. Die Praxis zeigt, dass selbst bei
umfangreichen Tests auch nachträglich immer wieder Fehler gefunden werden.
(c) Aussage: Die Worstcase-Zeitkomplexität von Binary Search für ein Array der
Grösse n ist TW (n) = O(log n).
Diese Aussage ist richtig.
Binary Search findet im schlechtesten Fall (Worstcase) einen Wert in einem
Array der Grösse n mit blog2 nc + 1 Vergleichen. Nimmt man den Vergleich als
primitive Operation, so ergibt sich daraus TW (n) = O(log n).
(d) Aussage: Die beiden Algorithmen A und B lösen ein bestimmtes Problem P.
Algorithmus A hat die Worstcase-Zeitkomplexität TW (n) = O(n2 ) und Algorithmus B hat die Worstcase-Zeitkomplexität TW (n) = O(n log n). Da die
Grössenordnungen der beiden Zeitkomplexitäten bekannt sind, steht fest, dass
Algorithmus B für jeden Input zeiteffizienter ausgeführt wird als Algorithmus
A.
Diese Aussage ist falsch.
Die Worstcase-Zeitkomplexitäten sind nur von ihrer Grössenordnung (LandauNotation) her bekannt. D.h. für Inputs ab einer gewissen Grösse, wird Algorithmus B mit TW (n) = O(n log n) im Worstcase effizienter sein als Algorithmus A
mit TW (n) = O(n2 ).
Für kleine Inputs muss dies allerdings nicht gelten, falls wir z.B. von folgenden
exakten Komplexitätsfunktionen ausgehen, ist Algorithmus B erst ab einer Inputgrösse von n ≥ 283 effizienter:
Algorithmus A: TW (n) = n2 + 2 = O(n2 )
Algorithmus B: TW (n) = 25n log2 9n + 20 = O(n log n)
2. Das Problem der Prüfung, ob ein Vektor A als Subvektor in einem anderen Vektor B enthalten ist, entstammt dem Fachgebiet der Mustererkennung (engl. pattern
recognition).
Der in dieser Aufgabe vorgestellte naive Probieralgorithmus löst dieses Problem
zwar, ist mit seiner Worst-Case-Zeitkomplexität TW (n, m) = O(n · m) (vgl. untenstehende Herleitung) allerdings sehr ineffizient. Dieser Algorithmus ist daher für
die Praxis nur bedingt geeignet.
Es gibt Algorithmen, deren Laufzeit auch im ungünstigsten Fall (Worst Case)
O(n + m) beträgt. Der sog. KMP-Algorithmus, benannt nach den Erfindern D.E.
U NIVERSIT ÄT B ERN
I NFORMATIK
VORLESUNG
EI
T YP
UL
B LATT
3 (2/3)
AUSGABE
HS 08
Knuth, J.H. Morris und V.R. Pratt, sei hier als ein Beispiel erwähnt.
In der Regel interessiert man sich v.a. für eine obere Schranke der Komplexität eines
Algorithmus. Deshalb wird oft nur die Komplexität im Worst Case angegeben.
Um die Average-Case-Komplexität bestimmen zu können, reicht es oft nicht aus,
nur den Algorithmus zu analysieren. Man muss zusätzlich für eine konkrete Anwendung die Inputs und deren Häufigkeiten analysieren, um bestimmen zu können, wie
der durchschnittliche Input überhaupt aussieht. Und diese Bestimmung des durchschnittlichen Inputs kann z.T. aufwändig sein.
(a) Zeitkomplexität des naiven Probieralgorithmus:
Als elementare Operation zählt man den Vergleich von zwei Elementen aus den
Vektoren. Im ungünstigsten Fall werden die äussere Schleife (n − m + 1)-mal
und die innere Schleife bis zu m-mal durchlaufen. Es gilt also:
TW (n, m) = (n − m + 1) · m = nm − m2 + m = O(n · m)
Da der Vektor A maximal so gross wie der Vektor B sein kann, sind die beiden
Längen m und n voneinander abhängig. Man kann desshalb in diesem Beispiel
davon ausgehen, dass m = 12 n gilt und somit:
1
1
1
1
1
1
1
TW (n, m) = (n − n + 1) · n = n2 − n2 + n = n2 + n = O(n2 )
2
2
2
4
2
4
2
(b) Platzkomplexität des naiven Probieralgorithmus:
Um die Platzkomplexität zu bestimmen, muss man zuerst definieren, welche
atomaren Variablen man zählt.
Die Analyse des Algorithmus ergibt z.B. folgende atomaren Variablen:
•
•
•
•
•
Vektor A mit m atomaren Variablen
Vektor B mit n atomaren Variablen
Laufvariable i der äusseren Schlaufe als 1 atomare Variable
Laufvariable j der inneren Schlaufe als 1 atomare Variable
Resultat vom Typ Boolean als 1 atomare Variable
Die Speicherplatzkomplexität ist also: S(n, m) = n + m + 3 = O(n + m)
Da der Vektor A maximal so gross wie der Vektor B sein kann, sind die beiden
Längen m und n voneinander abhängig. Man kann desshalb davon ausgehen,
dass maximal m = n gilt und somit: SW (n, m) = n + n + 3 = O(n)
3. Es muss gezeigt werden, dass die Umrechung des Logarithmus zur Basis a in einen
Logarithmus zur Basis b nur eines multiplikativen Faktors k > 0 bedarf:
Aus der Mathematik weiss man, dass loga x = log1 a · logb x ist (a, b > 1).
b
Da k = log1 a eine positive Konstante ist, sind loga x und logb x von der gleichen
b
Grössenordnung.
U NIVERSIT ÄT B ERN
I NFORMATIK
VORLESUNG
EI
T YP
UL
B LATT
3 (3/3)
AUSGABE
HS 08
4. Beispiele für einfache Algorithmen quadratischer Zeitkomplexität:
• Bubble-Sort, ein naiver Algorithmus zum Sortieren von n ganzen
Zahlen:
void Algorithm bubbleSort(int[] array):
// Input : Array/Vektor ganzer Zahlen der Grösse n
// Output: Input-Array wird als Seiteneffekt sortiert (inplace Sort)
// Zweck : Sortiert einen Array ganzer Zahlen aufsteigend
for (int i=0; i<n-1; i++)
// bubble up i-th record
for (int j=n-1; j>i; j--)
// bubble to the front
if (array[j] < array[j-1])
// records in wrong order?
swap(array, j, j-1);
// swap the two records
Die Inputgrösse sei hier n.
Die Zeitkomplexität ist TB (n) = TA (n) = TW (n) = O(n2 ).
Es gibt effizientere Algorithmen, weshalb Bubble-Sort für die Praxis nur bedingt
geeignet ist.
• Matrix-Vektor-Multiplikation:
Geht man davon aus, dass die Multiplikation zweier Zahlen eine atomare Operation sei, so ist die bekannte Mulitplikation einer quadratischen nxn-Matrix mit
einem Vektor der Grösse n ein Algorithmus mit quadratischer Zeitkomplexität.
Vektor Algorithm mult(Matrix M, Vektor v):
// Input : Quadratische Matrix der Grösse nxn, Vektor v der Grösse n
// Output: Vektor der Grösse n
// Zweck : Berechnet das Produkt M*v
Vektor result = Nullvektor der Grösse n
for (int i=0; i<n-1; i++)
for (int j=0; j<n-1; j++)
result[i]=result[i]+M[i,j]*v[i]
return result
Die Inputgrösse sei hier n.
Die Zeitkomplexität ist TB (n) = TA (n) = TW (n) = O(n2 ).
Herunterladen