C'è qualche studio o teoria dietro la combinazione della ricerca binaria e della ricerca di interpolazione?


14

Ho appena letto Questo algoritmo può ancora essere considerato un algoritmo di ricerca binaria? e ha ricordato che qualche anno fa ho scritto un indicizzatore / ricerca di file di registro per trovare voci di registro in file di testo di grandi dimensioni in base alla finestra data / ora.

Mentre facevo questo, ho deciso di provare la ricerca di interpolazione (non sapevo come si chiamava, mi sono imbattuto nell'idea da solo). Quindi, per qualche motivo, ho continuato a pensare di alternare i passaggi di interpolazione con i passaggi di divisione binaria: sul passaggio 0 interpolerei per decidere il punto di prova, quindi il passaggio 1 prenderei il punto medio esatto, ecc.

Ho quindi confrontato il sistema usando la ricerca di interpolazione pura, la ricerca binaria pura e il mio tentativo di combinazione. L'approccio alternativo è stato un chiaro vincitore, sia nel tempo che nel numero di test richiesti prima di trovare una serie di tempi scelti casualmente.

Ispirato alla domanda collegata, ho appena fatto una rapida ricerca di "ricerca di interpolazione alternata e ricerca binaria" e non ho trovato nulla. Ho anche provato la "ricerca di interpolazione coperta" come suggerito nel mio commento su una delle risposte.

Mi sono imbattuto in una cosa conosciuta? C'è qualche giustificazione teorica per essere più veloce per alcuni tipi di dati? I file di registro erano in genere di grandi dimensioni per il tempo (ad esempio 1-2 GB di testo con forse 10 milioni di righe da cercare) e la diffusione di date / orari era complessa con forti esplosioni di attività, tempi di punta generali e periodi di quiete. I miei test di riferimento sono stati campionati da una distribuzione uniforme dei tempi target da trovare.

Risposte:


5

Mi sono imbattuto in una cosa conosciuta?

O(log log n)O(log n)

  • La ricerca introspettiva è il tuo metodo (iterando tra una ricerca di interpolazione e una ricerca binaria). Non ho ulteriori dettagli.
  • Interpolazione-ricerca binaria (IBS) di N. Santoro, JB Sidney (1985).

    L'idea generale è che la ricerca per interpolazione sia utile solo quando l'array cercato è più grande di una determinata soglia. Quando il segmento di ricerca considerato è più piccolo di una soglia definita dall'utente, la ricerca binaria viene applicata incondizionatamente. Viceversa, oltre tale soglia, viene applicato un passaggio di ricerca di interpolazione, seguito infine da un passaggio di ricerca binario.

    Questo ha molti punti in comune con il tuo approccio.

  • Ricerca adattiva (AS) di Biagio Bonasera, Emilio Ferrara, Giacomo Fiumara, Francesco Pagano, Alessandro Provetti

    Usando le parole degli autori:

    [Interpolazione-ricerca binaria] ha ideato una soluzione simile che combina (ma non si fonde) tra interpolazione e ricerca binaria. Sebbene la complessità asintotica sia la stessa, ci sono alcune differenze marcate.

    [TAGLIARE]

    Pertanto, è possibile dimostrare che per qualsiasi input AS non richiederà più operazioni elementari di IBS.

    L'algoritmo può spendere fino al doppio numero di operazioni rispetto alla ricerca di interpolazione "semplice" per scoprire con attenzione il miglior dimezzamento del segmento di ricerca, il che a sua volta significherà che saranno necessarie meno iterazioni per completare (ma hai un overhead ancora maggiore) .


6

Interlacciare due algoritmi per ottenere il meglio da entrambi i mondi è una tecnica nota, anche se di solito si dice che li esegue in "parallelo" e restituisce una risposta non appena uno dei due termina.

Sebbene teoricamente più veloce, la ricerca per interpolazione presenta due svantaggi rispetto alla ricerca binaria:

  • Ha prestazioni terribili (lineari) nel peggiore dei casi

  • Il sovraccarico del calcolo del punto medio è piuttosto grande; un'iterazione di ricerca binaria è centinaia di volte più veloce di una ricerca di interpolazione

Mi aspetterei che un approccio in cui si esegue la ricerca di interpolazione mentre l'intervallo è grande e si passa alla ricerca binaria quando l'intervallo diventa piccolo sia il più efficiente. Sarebbe bello se tu potessi provare questo esperimento.

lognloglognlognloglogn

Penso che i tuoi risultati possano essere spiegati da due fenomeni:

  • La combinazione con la ricerca binaria consente di evitare il comportamento peggiore

  • L'effetto positivo del passaggio alla ricerca binaria su un piccolo set di dati


3
Hai scritto: "un'iterazione di ricerca binaria è centinaia di volte più veloce di una di ricerca di interpolazione". Si noti che nel caso di OP, la differenza tra calcolare il punto medio in questi due metodi è ridotta dal tempo di I / O necessario per recuperare il valore del punto medio.
liori,

@liori: le prime iterazioni ripetute di ricerche binarie sugli stessi dati potrebbero essere più compatibili con la cache, poiché vengono utilizzati gli stessi pochi elementi. Quindi ci si può aspettare che i quarti e forse gli ottavi restino caldi nella cache. Iniziare con binario e passare a interpolato dopo tre iterazioni potrebbe avere senso, se gli intervalli sono abbastanza grandi. (O se è possibile eseguire l'I / O asincrono e utilizzare il risultato che arriva per primo).
Peter Cordes,

Inoltre, anche per una ricerca in memoria, una cache miss (latenza di oltre 200 cicli) ha un paio di volte la latenza anche di una divisione intera a 64 bit (32-96 cicli), ad esempio su Intel Haswell . La divisione intera a 32 bit è significativamente più veloce (22-29 cicli). La larghezza di banda della memoria principale è una risorsa condivisa per tutti i core, ma la divisione intera utilizza solo risorse duplicate su ciascun core.
Peter Cordes,

2
Tuttavia, la latenza della memoria è molto peggio della larghezza di banda della memoria, poiché anche gli accessi sparsi multipli vanno più veloci se sono in volo contemporaneamente. È una vittoria precaricare (con le prefetcht0istruzioni ) entrambe le possibilità per l'iterazione SUCCESSIVA prima di caricare il punto medio corrente, per una ricerca in memoria sul moderno hardware x86. Non puoi farlo se non riesci a prevedere in anticipo i successivi indirizzi di recupero. Quindi i dettagli di implementazione pratica possono essere significativi, a parte considerazioni teoriche .
Peter Cordes,

@liori: Sicuramente l'I / O per punto medio è stato il fattore principale durante l'indicizzazione di un file di registro, poiché veniva letto su richiesta per trovare i record. Probabilmente c'erano più di due ordini di grandezza tra il calcolo dell'offset nel file e la lettura di un blocco - quindi il numero di punti medi calcolati sarebbe il fattore decisivo. Penso che se eseguo la replica ora senza un file di registro da indicizzare - qualcosa che cercherò di pubblicare qui - che potrebbe non esserci una differenza di velocità misurabile, ma potrebbe esserci una differenza misurabile "numero di punti medi necessari".
Neil Slater,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.