SPECYFIKACJA Problem: Jednoczesne wyszukiwanie elementu największego i najmniejszego w nieuporządkowanym ciągu liczb. DANE WEJŚCIOWE Ciąg n liczb umieszczonych w tablicy L. DANE WYJŚCIOWE Para indeksów dla elementu najmniejszego i elementu największego w ciągu L.
Chcemy jednocześnie odnaleźć elementy najmniejszy i największy w podanym zbiorze n elementowym. Metoda siłowa polega na znalezieniu najpierw elementu najmniejszego, a następnie największego. Tak działa pierwsza wersja funkcji minimax, która zwraca parę indeksów - dla elementu minimalnego i maksymalnego. Liczba wykonywanych porównań wynosi 2n-2.
def minimax(L, left, right): """Wyszukiwanie elementu najmniejszego i największego. Zastosowanie metody siłowej.""" mini = find_min(L, left, right) maxi = find_max(L, left, right) return (mini, maxi) # zwraca krotkę indeksów
Lepszym podejściem jest algorytm minimax. Postępujemy wg zasady dziel i zwyciężaj (divide and conquer).
Dla n = 2k liczba porównań wynosi P = k+2(k-1) = 3k-2 = (3n-4)//2. Dla n = 2k+1 liczba porównań wynosi P = k+2k = 3k = (3n-3)//2. Złożoność algorytmu jest rzędu (3/2)n.
def minimax(L, left, right): """Wyszukiwanie elementu najmniejszego i największego. Zastosowanie metody dziel i zwyciężaj.""" if left == right: # tylko jeden element w zbiorze return (left, left) # co najmniej 2 elementy if L[left] > L[left+1]: maxi = left mini = left+1 else: maxi = left+1 mini = left k = left+2 # już może nie istnieć! while k < right: # pobieramy pary if L[k] > L[k+1]: if L[k] > L[maxi]: maxi = k if L[k+1] < L[mini]: mini = k+1 else: if L[k+1] > L[maxi]: maxi = k+1 if L[k] < L[mini]: mini = k k = k+2 if k == right: # nieparzysta liczba elementów if L[k] > L[maxi]: maxi = k if L[k] < L[mini]: mini = k return (mini, maxi)