Binäärihaku on algoritmi, jolla voi löytää tietyn alkion alkion järjestetystä taulukosta ajassa . Tutustumme seuraavaksi binäärihaun toteuttamiseen sekä sen soveltamiseen algoritmiikassa.
Haun toteutus
Mukava tapa toteuttaa binäärihaku on aloittaa taulukon alusta ja kulkea sitä eteenpäin hyppäyksin. Hypyn pituus on ensin , sitten , sitten , jne., kunnes lopuksi pituus on . Jokaisen pituuden kohdalla hypitään eteenpäin, kunnes seuraava hyppy veisi taulukon ulkopuolelle tai alkioon, joka on liian suuri.
Seuraava esimerkki etsii alkion sijainnin järjestetyssä taulukossa , jossa on alkiota:
int k = 0; for (int b = n; b >= 1; b /= 2) { while (k+b < n && t[k+b] <= x) k += b; } if (t[k] == x) // alkio löytyi
Muuttuja ilmaisee kohdan taulukossa, ja se on aluksi . Muuttuja määrittää hypyn pituuden. Jos taulukossa on alkio , sen kohta on lopuksi muuttujassa .
Algoritmi vie aikaa , koska hypyn pituuksia on yhteensä ja jokaisen pituuden kohdalla while-silmukkaa suoritetaan enintään kaksi kierrosta.
Toistuvat alkiot
Äskeisessä binäärihaun toteutuksessa on etuna, että sitä on helppoa muokata eri tilanteisiin sopivaksi. Esimerkiksi seuraava koodi laskee, montako kertaa järjestetyssä taulukossa esiintyy alkio :
int k1 = -1, k2 = -1; for (int b = n; b >= 1; b /= 2) { while (k1+b < n && t[k1+b] < x) k1 += b; while (k2+b < n && t[k2+b] <= x) k2 += b; } c = k2-k1; // toistuvien alkioiden määrä
Tässä ideana on, että muuttujaan etsitään viimeinen kohta, jossa taulukon alkio on alle , ja muuttujaan etsitään viimeinen kohta, jossa taulukon alkio on enintään . Niinpä on alkion toistokertojen määrä taulukossa.
Muutoskohdan etsiminen
Binäärihaun pääasiallinen käyttötarkoitus algoritmiikassa ei ole alkioiden etsiminen taulukosta vaan funktion muutoskohdan etsiminen.
Oletetaan, että meillä on funktio , jolle pätee , kun , ja , kun . Binäärihaun avulla löydämme tehokkaasti muutoskohdan näin:
int k = -1; for (int b = N; b >= 1; b /= 2) { while (f(k+b) == 0) k += b; } int m = k+1;
Tässä on sopiva yläraja, jossa varmasti , ja haku etsii viimeisen kohdan , jolle pätee . Niinpä haun päätteeksi . Haku vie aikaa .
Esimerkki: Tehdas
Tarkastellaan tehtävää (tämän viikon tehtävä 1), jossa tehtaassa on konetta, jotka on numeroitu . Koneella vie minuuttia aikaa valmistaa yksi tuote. Mikä on pienin aika, jossa voimme valmistaa tuotetta?
Hyödyllinen havainto on, että jos aikaa on minuuttia, voimme valmistaa koneella yhteensä tuotetta. Vastaavasti käyttämällä kaikkia koneita voimme valmistaa minuutissa tuotetta.
Voimme ratkaista tehtävän binäärihaun avulla muotoilemalla funktion niin, että , jos , ja muuten . Nyt funktion muutoskohta kertoo, mikä on pienin määrä aikaa, jossa voimme valmistaa tuotetta.
Jotta voimme käyttää binäärihakua, meidän tulee valita jotenkin parametri . Mahdollinen valinta on . Tämä tarkoittaa, että valmistamme kaikki tuotteet koneen avulla. Tämä ei selkeästi ole yleensä hyvä tapa, koska muita koneita ei käytetä lainkaan, mutta saamme tästä ylärajan vastaukselle.
Tuloksena oleva algoritmi vie aikaa , koska binäärihaussa on askelta ja jokaisen suorittaminen vie aikaa .