Algoritmit 2 Luento 7 Ti 4.4.2017 Timo Männikkö
Luento 7 Joukot Joukko-operaatioita Joukkojen esitystapoja Alkiovieraat osajoukot Toteutus puurakenteena Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 2/26
Joukot Joukko: Kokoelma alkioita Yksittäisiin alkioihin kohdistuvat operaatiot Useampaan joukkoon kohdistuvat operaatiot Esitystapaan vaikuttavat mm. Mikä on perusjoukko, mitä osajoukkoja käsitellään Voiko sama alkio esiintyä useammin samassa joukossa Voidaanko/tarvitseeko alkiot järjestää Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 3/26
Joukko-operaatioita Kuuluuko alkio x (osa)joukkoon A Mihin osajoukkoon alkio x kuuluu Lisää alkio x joukkoon A Poista alkio x joukosta A Käydään läpi joukon A alkiot jossain järjestyksessä Etsitään joukon pienin tai suurin alkio (jos alkioiden järjestys määritelty) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 4/26
Joukko-operaatioita Joukon A asettaminen samaksi kuin toinen joukko B (esimerkiksi tyhjäksi joukoksi ) Testataan, ovatko joukot A ja B samat Joukkojen A ja B leikkaus A B Joukkojen A ja B yhdiste (unioni) A B Joukkojen A ja B erotus A \ B Ovatko joukot A ja B alkiovieraita (A B = ) Alkiovieraiden joukkojen A ja B yhdiste eli merge-operaatio Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 5/26
Joukkojen esitystapoja Joukkojen identifiointi tunnuksella: Jokaisella (osa)joukolla tunnus (nimi, numero) Jokaiseen alkioon liittyy tieto (indeksi, osoitin), joka kertoo mihin joukkoon se kuuluu Joukkoon kuuluminen ja alkioiden siirtely yksinkertaisia operaatioita (vakioaikaisia) Muut operaatiot vaativat kaikkien alkioiden läpikäynnin Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 6/26
Joukkojen esitystapoja Linkitetty lista: Useimpien joukko-operaatioiden tehokas suoritus Taulukko: Sopii, jos (osa)joukoissa ei tapahdu paljon muutoksia Binääripuu: Yksittäisiä alkioita koskevien operaatioiden tehokas suoritus Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 7/26
Joukkojen esitystapoja Bittivektoriesitys: Sopii, jos perusjoukon alkioiden lkm n ei ole kovin suuri Jokainen alkio taulukossa, viittaus alkioon taulukkoindeksillä Jokaista (osa)joukkoa kohti on n:n bitin bittivektori Alkio i kuuluu joukkoon a, jos a[i] = 1 Alkio i ei kuulu joukkoon a, jos a[i] = 0 (Tai boolean-tyyppinen taulukko: a[i] = true tai false) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 8/26
Operaatiot bittivektoreille Kaikki joukko-operaatiot yksinkertaisia Esimerkiksi yhdiste c = a b: union(a, b, c) { for (int i = 0; i < n; i++) c[i] = a[i] b[i]; } Mutta: Aikavaativuus Θ(n) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 9/26
Alkiovieraat osajoukot Union-find (tai merge-find) -tehtävä: Joukko alkioita, jotka kaikki muodostavat aluksi yhden alkion osajoukon Osajoukkoja yhdistellään isommiksi osajoukoiksi Osajoukot säilyvät alkiovieraina Tarvittavat operaatiot: find: Etsi, missä osajoukossa alkio tällä hetkellä on union: Yhdistä kaksi osajoukkoa yhdeksi osajoukoksi Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 10/26
Operaatioiden toteutus Joukot linkitetyissä listoissa: Joukolla osoitin sekä ensimmäiseen että viimeiseen alkioon find: Käydään listat läpi Θ(n) union: Yhdistetään listat Θ(1) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 11/26
Operaatioiden toteutus Joukot taulukossa: Taulukon indeksi i tarkoittaa alkiota i Taulukon paikassa i on sen osajoukon tunnus, johon alkio i kuuluu find: Tutkitaan indeksin osoittama paikka Θ(1) union: Käydään taulukko läpi Θ(n) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 12/26
Toteutus puurakenteena Joukon alkiot puun solmuja Yksi puu esittää yhtä osajoukkoa Kaikki perusjoukon osajoukot muodostavat useamman puun metsän Mikä tahansa puun solmu voi olla juurisolmu Mitkä tahansa puun solmuista voivat olla juurisolmun lapsia, näiden lapsia, jne. Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 13/26
Toteutus puurakenteena Juurisolmu identifioi kyseisen osajoukon Muista solmuista on linkki vanhempaan find(x): Lähdetään solmusta x kohti juurta Kun päästään juureen, tiedetään osajoukko union(a, b): Tunnetaan osajoukkojen juurisolmut a ja b Asetetaan toisen osajoukon juurisolmu toisen osajoukon juurisolmun lapseksi Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 14/26
Operaatioiden lukumäärä Yhdisteen muodostaminen: Etsitään ensimmäisen osajoukon juurisolmu Etsitään toisen osajoukon juurisolmu Yhdistetään puut Jokaista union:ia edeltää kaksi find:ia Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 15/26
Operaatioiden aikavaativuus union: Puiden yhdistäminen vakioaikainen find: Vaativuus riippuu puun korkeudesta Pyritään pitämään puiden korkeudet mahdollisimman pieninä Muokataan operaatioita vastaavasti Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 16/26
Operaatioiden aikavaativuus union: Valitaan yhdisteen juurisolmuksi suuremman osajoukon juurisolmu Liitetään pienemmän osajoukon juuri yhdisteen juuren lapseksi Jos solmuja m, puun korkeus log(m + 1) find: Pienennetään kuljetun polun pituutta Hakupolun tiivistys: Siirretään polulla olevat solmut juurisolmun lapsiksi Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 17/26
Operaatioiden toteutus Alkiot kokonaislukuja väliltä 1... n Tallennusvektori pvjoukko Joukon tunnus juurisolmun indeksi Juurisolmua vastaavaan paikkaan tallennetaan kyseisen osajoukon alkioiden lukumäärä Lukumäärä tallennetaan vastalukuna, jotta juurisolmu tunnistetaan Muita solmuja vastaaviin paikkoihin tallennetaan kyseisen solmun vanhemman indeksi Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 18/26
Esimerkki 2 4 5 8 10 1 3 7 6 9 1 2 3 4 5 6 7 8 9 10 2-2 4-3 -1 10 4-1 10-3 Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 19/26
Esimerkki jatkuu 2 1 5 10 6 9 4 3 7 8 1 2 3 4 5 6 7 8 9 10 2-6 4-4 2 10 4 4 10 2 Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 20/26
Operaatioiden toteutus void union(int a, int b) // Oletus: a ja b juurisolmuja { int k; k = pvjoukko[a] + pvjoukko[b]; if (pvjoukko[a] <= pvjoukko[b]) { pvjoukko[b] = a; pvjoukko[a] = k; } else { pvjoukko[a] = b; pvjoukko[b] = k; } } Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 21/26
Operaatioiden toteutus int find(int x) { int j, k; // Juurisolmun etsintä: j = x; while (pvjoukko[j] > 0) j = pvjoukko[j]; // Hakupolun tiivistys: while (pvjoukko[x] > 0) { k = x; x = pvjoukko[x]; pvjoukko[k] = j; } return j; } Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 22/26
Operaatioiden toteutus Yleinen kahden joukon yhdiste: a = find(a); b = find(b); union(a, b); Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 23/26
Esimerkki jatkuu find(6) find(7) palauttaa 2 palauttaa 4 hakupolun tiivistys (hakupolun tiivistys) 2 1 5 6 10 9 4 3 7 8 1 2 3 4 5 6 7 8 9 10 2-6 4-4 2 2 4 4 10 2 Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 24/26
Esimerkki jatkuu union(2,4) kutsuttaessa 2 ja 4 juurisolmuja 2 1 4 5 6 10 3 7 8 9 1 2 3 4 5 6 7 8 9 10 2-10 4 2 2 2 4 4 10 2 Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 25/26
Operaatioiden aikavaativuus Perusjoukossa n alkiota Aluksi jokainen alkio muodostaa oman yhden alkion osajoukkonsa Korkeintaan n 1 kpl union-operaatioita Suoritetaan m kpl find-operaatioita... Pahimman tapauksen aikavaativuus Θ(n + m log n) Funktio log erittäin hitaasti kasvava, käytännössä log n 5 (mutta ei vakio) Algoritmit 2 Kevät 2017 Luento 7 Ti 4.4.2017 26/26