L'algoritmo ternary search è un algoritmo veloce per trovare il minimo o il massimo di un unimodal function, una funzione che sia aumenta e poi diminuisce o diminuisce e poi aumenta. Supponiamo di avere a che fare con una funzione che diminuisce, poi aumenta e che vogliamo trovare il minimo di valore. La ricerca ternaria funziona utilizzando la seguente ricorsione:La ricerca ternaria è meno efficiente di questo algoritmo correlato?
- Se la dimensione della finestra è "abbastanza piccola", è sufficiente tornare al punto centrale.
- Altrimenti:
- Valutare la funzione ai limiti sinistro e destro; chiama i valori l e r.
- Valutare la funzione ai punti 1/3 e 2/3; chiamare i valori m e m
- Se m < m 2 , allora siamo nella crescente regione della funzione e il minimo non può essere compresa tra 2 m e r .
- Se m > m 2 , allora siamo nella regione diminuzione della funzione può minimo non può essere compresa tra L e M
- ricorsivamente 2/3 che weren' t scartato.
Questo algoritmo funziona in modo rapido, perché può continuare a tirare fuori 1/3 dei valori su ogni iterazione.
Tuttavia, mi sento come se mi mancasse qualcosa perché credo che possiamo far funzionare questo algoritmo molto più velocemente. In particolare, notiamo che stiamo sempre proiettando uno dei terzi dell'intervallo tra un confine e uno dei punti sonda. Ciò significa che manteniamo la regione tra il punto di tastatura e l'altro limite. Poiché la ricerca ternaria seleziona i punti sonda a 1/3 punti, ciò significa che conserviamo 2/3 dei valori in ogni punto. E se invece di sondare i punti 1/3 e 2/3, abbiamo sondato il 1/2 - & epsilon; e 1/2 + & epsilon; punti per un estremamente piccolo & epsilon ;? Ciò significherebbe che dovremmo buttare fuori 1/2 - & epsilon; dell'intervallo su ogni passo, il che significa che la dimensione dell'intervallo diminuirà molto più rapidamente rispetto a quando avessimo appena lanciato un terzo degli elementi ogni volta.
Ad esempio, se prendo & epsilon; = 1/1000, otteniamo il lancio di 999/2000 dell'intervallo da cercare su ogni iterazione. La frazione rimanente dopo un certo numero di iterazioni qui viene mostrato (ricerca ternario si trova sulla sinistra, il mio algoritmo si trova sulla destra :)
1 : 1.0 >= 1.0
2 : 0.666666666667 >= 0.5005
3 : 0.444444444444 >= 0.25050025
4 : 0.296296296296 >= 0.125375375125
5 : 0.197530864198 >= 0.0627503752501
6 : 0.131687242798 >= 0.0314065628127
7 : 0.0877914951989 >= 0.0157189846877
8 : 0.0585276634659 >= 0.00786735183621
9 : 0.0390184423106 >= 0.00393760959402
10 : 0.0260122948737 >= 0.00197077360181
11 : 0.0173415299158 >= 0.000986372187705
12 : 0.0115610199439 >= 0.000493679279947
13 : 0.00770734662926 >= 0.000247086479613
14 : 0.00513823108617 >= 0.00
15 : 0.00342548739078 >= 6.18952249147e-05
16 : 0.00228365826052 >= 3.09785600698e-05
17 : 0.00152243884035 >= 1.55047693149e-05
18 : 0.00101495922690 >= 7.76013704213e-06
19 : 0.000676639484599 >= 3.88394858959e-06
È questa versione modificata dell'algoritmo solo "migliore" rispetto alla versione originale? O c'è qualcosa che mi manca qui significherebbe che non dovrei usare la strategia modificata per scegliere i punti sonda?
Dal mio punto di vista, il vantaggio della ricerca della sezione aurea è che valuta la funzione meno frequentemente perché può riutilizzare sonde su iterazioni, non perché è più numericamente stabile. Sono errato su questo? – templatetypedef
Questo è esattamente il caso. È abbastanza stabile rispetto all'estremo algoritmo di bisettrice, poiché i due punti medi sono ragionevolmente distribuiti. – Peteris