11.07.2015 Views

2014.1.futuro

2014.1.futuro

2014.1.futuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Muuttuja b määrittää, kuinka suuriahyppyjä haussa tehdään. Jokaisen hypynpituuden kohdalla liikutaan niin montahyppyä eteenpäin kuin mahdollista menemättätaulukon oikean reunan yli taisellaiseen lukuun, joka on etsittävää lukuasuurempi. Kuten aiemminkin, muuttujai on taulukkoon osoittava indeksi.Haun päätteeksi i osoittaa kohtaan, jossahaettava luku esiintyy taulukossa, mikälisellainen kohta on olemassa.Matemaattisesti ilmaistuna lineaarihakutarkistaa pahimmillaan n taulukonkohtaa, kun taas binäärihaku tarkistaavain noin log 2n kohtaa. Binäärihaun askeltenlogaritminen määrä johtuu siitä,että hypyn pituus puolittuu jokaisessavaiheessa. Lisäksi tiettyä hypyn pituuttavastaavia askelia tehdään käytännössäkorkeintaan kaksi. Ero n:n ja log 2n:n tarkistuksenvälillä on todella merkittävä,kun n on suuri luku. Esimerkiksi jos n onmiljoona, log 2n on vain noin 20.Mitä sillä tekee?Osaamme nyt koodata toimivan binäärihaun,mutta mihin sitä voisi käyttää?Yllättävää kyllä, binäärihakua käytetäännykyään harvoin järjestetystä taulukostahakemiseen, sillä useimmissaohjelmointikielissä on valmiina paljonmonipuolisempia tietorakenteita. EsimerkiksiC++:ssa voi käyttää std::setluokkaa,joka tukee tehokkaan haun lisäksimyös tehokasta alkion lisäämistä japoistamista.Binäärihaulla on kuitenkin muitakinsovelluksia. Tutkitaan vaikkapa tieverkkoa,jossa on kaupunkeja sekä kahdenkaupungin välisiä teitä. Jokaisesta tienpätkästätiedetään, paljonko polttoainettasillä ajaminen kuluttaa. Autot voivattankata kaupungeissa mutta eivät tieosuuksilla.Minkä kokoinen polttoainesäiliö autossatäytyy vähintään olla, jotta sillä voiajaa mistä vain kaupungista mihin tahansatoiseen kaupunkiin?2AC38BD5Kuva 1. Polttoaineongelman lähtöasetelma.Kuvassa 1 on esimerkki tieverkosta.Jokainen kuvan ympyrä vastaa kaupunkia,jotka on merkitty tunnuksin A, B, C jaD. Kaupunkien väliset tiet on merkitty viivoin.Esimerkiksi kaupungista B pääseekaupunkiin C kuluttamalla kolme litraapolttoainetta.Tehtävän ratkaisussa kannattaa ensinmiettiä yksinkertaisempaa ongelmaa: jospolttoainesäiliön koko on x litraa, onkomahdollista ajaa minkä tahansa kahdenkaupungin välillä?Ongelma ratkeaa näin: Valitaan mikätahansa kaupunki lähtökaupungiksi jamerkitään se ruksilla. Sitten merkitäänkaikki kaupungit, joihin lähtökaupungistapääsee x litralla polttoainetta. Tämänjälkeen merkitään vastaavasti kaikkikaupungit, joihin pääsee viimeksi merkityistäkaupungeista. Samaa toistetaanniin kauan kuin uusia kaupunkeja tuleemukaan. Jos lopussa kaikki kaupungit onmerkitty, x litraa riittää minkä tahansakahden kaupungin välillä ajamiseen.2AC38BDKuva 2. Mihin pääsee C:stä kolmen litran säiliöllä?2AC38BD55Kuva 3. Viiden litran säiliö riittää kaikkialle.Luodaan riittaa(x)-funktio, joka palauttaatrue, jos x litran säiliö riittää kaikkienkaupunkien välillä, ja muuten false. Jostehtävän ratkaisu on r litraa, riittaa(x)palauttaa false aina, kun x on r–1 tai vähemmän,ja true aina, kun x on r taienemmän.Funktion arvoissa on siis yksi muutoskohta,jonka vasemmalla puolella jokainenarvo on false ja oikealla puolellajokainen arvo on true. Lisäksi tiedämme,että kaupungista toiseen pääsee ainakinsilloin, kun polttoainesäiliö riittää kaikilletieosuuksille. Näiden ominaisuuksienansiosta tehtävän voi ratkaista tehokkaastibinäärihaulla funktiota riittaa(x)käyttäen:int v = 0;for (int b = s / 2; b >= 1; b /= 2)while (!riittaa(v + b))v += b;return v + 1;Muuttujassa s on tieverkon vaativimmantieosuuden polttoainekulutus. Tämäarvo on luonteva valinta binäärihaun ylärajaksi.Koodi laskee muuttujaan v suurimmanpolttoainemäärän, joka ei riitäminkä tahansa kahden kaupungin välilläajamiseen. Tehtävän vastaus on sitenyhden suurempi kuin tämä arvo. Binäärihaunansiosta funktiota riittaa(x) täytyykutsua vain noin log 2s kertaa.Vastaavaa menetelmää voi soveltaaaina, kun etsitään lukua ja osataan tunnistaa,onko jokin annettu luku pienempivai suurempi kuin etsitty luku. Binäärihaunansiosta ei tarvitse käydä läpi kaikkiamahdollisia arvoja vaan logaritminenmäärä riittää. Algoritmista tulee siis tehokas.21

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!