Prořezávej a hledej (Prune and search) je typ algoritmu založený na vyřazování neperspektivních dat – redukci velikosti problému. Toto paradigma je velmi podobné algoritmům typu rozděl a panuj (divide and conquer), zásadní rozdíl je ovšem v tom, že při prořezávání neprocházíme všechny větve, ale pouze ty, které pro nás dávají smysl.
Příklad
Pokud hledáme n-té nejvyšší číslo v neseřazeném poli, tak by řešením zajisté bylo pole seřadit a podívat se na zadaný index. Toto řešení ovšem není příliš efektivní. Lepším řešením je upravit například Quicksort tak, aby se po rozdělení pole dle pivota prohledávala pouze ta část, která obsahuje řešení - Quicksort v každém svém kroku umístí pivota na korektní místo v seřazeném poli, není proto problém rozhodnout, ve které části se nachází ono hledané číslo.
Složitost
Zatímco asymptotická složitost Quicksortu je a očekáváná
, tak díky eliminaci větví, které nemohou obsahovat řešení, je očekávaná složitost prune and search algoritmu
, kde c je malá konstanta.
Kód
01.
/**
02.
* Prorezavej a hledej
03.
* @param array prohledavane pole
04.
* @param index kolikatou nejvyssi hodnotu hledame (cislovano od 0)
05.
* @param left prvni levy prvek, na ktery muzeme sahnout
06.
* @param right prvni prvek, na ktery uz nemuzeme sahnout
07.
* @return index-ta nejvyssi hodnota
08.
*/
09.
public
static
int
pruneAndSearch(
int
[] array,
int
index,
int
left,
int
right) {
10.
int
boundary = left;
11.
for
(
int
i = left +
1
; i < right; i++) {
12.
if
(array[i] > array[left]) {
//primo za pivot posleme vse vetsi, nez je on sam
13.
swap(array, i, ++boundary);
14.
}
15.
}
16.
swap(array, left, boundary);
17.
//konec quicksortu
18.
19.
if
(boundary == index)
return
array[boundary];
//nalezli jsme
20.
else
if
(boundary > index)
return
pruneAndSearch(array, index, left, boundary);
//odrizneme pravou vetev
21.
else
return
pruneAndSearch(array, index, boundary +
1
, right);
//odrizneme levou vetev
22.
}
23.
24.
/**
25.
* Prohodi prvky v zadanem poli
26.
* @param array pole
27.
* @param left prvek 1
28.
* @param right prvek 2
29.
*/
30.
private
static
void
swap(
int
[] array,
int
left,
int
right) {
31.
int
tmp = array[right];
32.
array[right] = array[left];
33.
array[left] = tmp;
34.
}
Literatura
- Prune-and-search. In . [s.l.] : [s.n.], 2006 [cit. 2010-03-15]. Dostupné z WWW: <http://www.cs.duke.edu/courses/fall05/cps230/L-03.pdf>.