Wie Ariel bemerkt , ist der Standard-Maximum-Finding-Algorithmus wie folgt:
def find_maximum(a):
m = a[0]
for x in a:
if x > m: m = x
return m
wird in der Tat ohne Änderung funktionieren, solange:
- jedes Elementpaar kann verglichen werden, und
- Die Eingabe enthält garantiert ein maximales Element, dh ein Element, das paarweise größer ist als jedes andere Element in der Eingabe.
(Die obige erste Annahme kann tatsächlich gelockert werden, auch ohne dass der Algorithmus geändert werden muss, solange angenommen wird, dass das maximale Element mit jedem anderen Element vergleichbar ist und das x > y
immer falsch ist, wenn die Elemente x
und y
unvergleichbar sind.)
Insbesondere Ihre Behauptung, dass:
[…] Um eine Antwort zu erhalten, muss das Element explizit mit jedem anderen Element verglichen werden (da der Vergleich nicht transitiv ist).
trifft unter den oben angegebenen Annahmen nicht zu. Um zu beweisen, dass der obige Algorithmus immer das maximale Element findet, genügt es zu beachten, dass:
- da die Schleife über alle Eingabeelemente iteriert, wird bei einer gewissen Iteration
x
das maximale Element sein;
- da das maximale Element paarweise größer als jedes andere Element ist, folgt, dass am Ende dieser Iteration
m
das maximale Element ist; und
- Da kein anderes Element paarweise größer als das maximale Element sein kann,
m
ändert sich dies bei den nachfolgenden Iterationen nicht.
Daher ist am Ende der Schleife m
immer das maximale Element, wenn die Eingabe eins enthält.
Ps. Wenn die Eingabe nicht unbedingt immer ein maximales Element enthält, muss die Antwort des Kandidaten für jedes andere Element getestet werden, um zu überprüfen, ob sie wirklich maximal ist. Wir können dies jedoch immer noch in O ( n ) Zeit tun, nachdem der oben beschriebene Maximum-Finding-Algorithmus ausgeführt wurde:
def find_maximum_if_any(a):
# step 1: find the maximum, if one exists
m = a[0]
for x in a:
if x > m: m = x
# step 2: verify that the element we found is indeed maximal
for x in a:
if x > m: return None # the input contains no maximal element
return m # yes, m is a maximal element
(Ich gehe hier davon aus, dass die Relation >
irreflexiv ist, dh kein Element kann größer sein als sich selbst. Wenn dies nicht unbedingt der Fall ist, sollte der Vergleich x > m
in Schritt 2 durch ersetzt werden x ≠ m and x > m
, wobei ≠
Identitätsvergleich bedeutet. Oder wir könnten einfach die Optimierung anwenden Unten angegeben.)
Um die Richtigkeit dieser Variation des Algorithmus zu beweisen, betrachten Sie die beiden möglichen Fälle:
- Wenn die Eingabe ein maximales Element enthält, wird es in Schritt 1 (wie oben gezeigt) gefunden und in Schritt 2 bestätigt.
- Wenn der Eingang ist nicht ein maximales Element enthalten, wird der Schritt 1 wird am Ende wie einige beliebiges Element Kommissionierung
m
. Es spielt keine Rolle, um welches Element es sich handelt, da es in jedem Fall nicht maximal sein wird, und daher erkennt Schritt 2 dies und kehrt zurück None
.
Wenn wir den Index von m
in dem Eingabearray speichern a
, könnten wir Schritt 2 tatsächlich optimieren, um nur die Elemente zu überprüfen, die zuvor m
eingegangen sind a
, da alle späteren Elemente bereits mit m
Schritt 1 verglichen wurden. Diese Optimierung ändert jedoch nicht die Komplexität der asymptotischen Zeit des Algorithmus, der immer noch O ( n ) ist.