Harjoitustyö 3: It's a social network, baby!

Samankaltaiset tiedostot
Harjoitustyö 2: Henkilötietojärjestelmä

Harjoitustyö 1: Palkkatilastot

Harjoitustyö 1: Kaupungit

Harjoitustyö 2: Game of Taxes

Harjoitustyö 1: Beacons of RGB

Harjoitustyö 3: Roads are coming

Harjoitustyö 2: Game of Fibres

Tässä tehtävässä käsittelet metodeja, listoja sekä alkulukuja (englanniksi prime ).

Ohjelmoinnin jatkokurssi, kurssikoe

Harjoitustyö 3 - Millosemeni

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 1. Demot Timo Männikkö

TAMPEREEN TEKNILLINEN YLIOPISTO

TAMPEREEN TEKNILLINEN YLIOPISTO

Tietorakenteet ja algoritmit syksy Laskuharjoitus 1

58131 Tietorakenteet ja algoritmit (syksy 2015)

ITKP102 Ohjelmointi 1 (6 op)

Olio-ohjelmointi Syntaksikokoelma

ITKP102 Ohjelmointi 1 (6 op)

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Luento 12 Ti Timo Männikkö

ITKP102 Ohjelmointi 1 (6 op)

Informaatioteknologian laitos Olio-ohjelmoinnin perusteet / Salo

811120P Diskreetit rakenteet

Oliosuunnitteluesimerkki: Yrityksen palkanlaskentajärjestelmä

Tietorakenteet ja algoritmit - syksy

Tietorakenteet (syksy 2013)

Zeon PDF Driver Trial

f(n) = Ω(g(n)) jos ja vain jos g(n) = O(f(n))

Algoritmit 2. Luento 2 Ke Timo Männikkö

Taulukot. Taulukon määrittely ja käyttö. Taulukko metodin parametrina. Taulukon sisällön kopiointi toiseen taulukkoon. Taulukon lajittelu

811312A Tietorakenteet ja algoritmit, , Harjoitus 3, Ratkaisu

Kääreluokat (oppikirjan luku 9.4) (Wrapper-classes)

Algoritmit 1. Luento 12 Ke Timo Männikkö

Algoritmit 2. Luento 2 To Timo Männikkö

private TreeMap<String, Opiskelija> nimella; private TreeMap<String, Opiskelija> numerolla;

Algoritmit 1. Luento 1 Ti Timo Männikkö

Lausekielinen ohjelmointi II Ensimmäinen harjoitustyö

Harjoitus 4 (viikko 47)

Kirjoita oma versio funktioista strcpy ja strcat, jotka saavat parametrinaan kaksi merkkiosoitinta.

Ohjelmoinnin perusteet Y Python

A TIETORAKENTEET JA ALGORITMIT

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Hakemistojen sisällöt säilötään linkitetyille listalle.

Algoritmit 2. Luento 1 Ti Timo Männikkö

Toinen harjoitustyö. ASCII-grafiikkaa

Maahan on pudonnut omenoita, ja Uolevi aikoo poimia niitä. Tiedät jokaisesta omenasta, kuinka painava se on.

Ohjelmoinnin perusteet, kurssikoe

Algoritmit 2. Luento 7 Ti Timo Männikkö

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

(p j b (i, j) + p i b (j, i)) (p j b (i, j) + p i (1 b (i, j)) p i. tähän. Palaamme sanakirjaongelmaan vielä tasoitetun analyysin yhteydessä.

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

Harjoitus 5. Esimerkki ohjelman toiminnasta: Lausekielinen ohjelmointi I Kesä 2018 Avoin yliopisto 1 / 5

2. Lisää Java-ohjelmoinnin alkeita. Muuttuja ja viittausmuuttuja (1/4) Muuttuja ja viittausmuuttuja (2/4)

Algebralliset tietotyypit ym. TIEA341 Funktio ohjelmointi 1 Syksy 2005

Ohjelmoinnin peruskurssi Y1

Harjoitus 3 (viikko 39)

Tietorakenteet ja algoritmit Johdanto Lauri Malmi / Ari Korhonen

Harjoitus 6 (viikko 42)

Harjoitus 5 (viikko 41)

Sisältö. 2. Taulukot. Yleistä. Yleistä

2 Konekieli, aliohjelmat, keskeytykset

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

Algoritmit 1. Luento 3 Ti Timo Männikkö

1. (a) Seuraava algoritmi tutkii, onko jokin luku taulukossa monta kertaa:

Tietorakenteet, laskuharjoitus 3, ratkaisuja

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Ohjelmoinnin perusteet Y Python

ITKP102 Ohjelmointi 1 (6 op), arvosteluraportti

Sisältö. 22. Taulukot. Yleistä. Yleistä

1. Mitä tehdään ensiksi?

Linkitetystä listasta perittyä omaa listaa käytetään muun muassa viestiin liittyvien vastausten säilömiseen.

Rakenteiset tietotyypit Moniulotteiset taulukot

Algoritmit 1. Luento 7 Ti Timo Männikkö

JAVA-PERUSTEET. JAVA-OHJELMOINTI 3op A JAVAN PERUSTEET LYHYT KERTAUS JAVAN OMINAISUUKSISTA JAVAN OMINAISUUKSIA. Java vs. C++?

4 Tehokkuus ja algoritmien suunnittelu

Ohjelmoinnin perusteet Y Python

Sisällys. 18. Abstraktit tietotyypit. Johdanto. Johdanto

OHJ-1160 Laaja Ohjelmointi 2

Ohjelmoinnin perusteet Y Python

Metropolia ammattikorkeakoulu TI00AA : Ohjelmointi Kotitehtävät 3 opettaja: Pasi Ranne

18. Abstraktit tietotyypit 18.1

TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos. Harjoitustyö 4: Cache, osa 2

Luento 5. Timo Savola. 28. huhtikuuta 2006

Algoritmit 2. Luento 14 Ke Timo Männikkö

811312A Tietorakenteet ja algoritmit, , Harjoitus 7, ratkaisu

Maastotietokannan torrent-jakelun shapefile-tiedostojen purkaminen zip-arkistoista Windows-komentojonoilla

Algoritmit 2. Demot Timo Männikkö

Metodit. Metodien määrittely. Metodin parametrit ja paluuarvo. Metodien suorittaminen eli kutsuminen. Metodien kuormittaminen

List-luokan soveltamista. Listaan lisääminen Listan läpikäynti Listasta etsiminen Listan sisällön muuttaminen Listasta poistaminen Listan kopioiminen

Ohjelmointi 2 / 2010 Välikoe / 26.3

Ohjelmointi 1 C#, kevät 2013, 2. tentti

Harjoitustyö: virtuaalikone

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Ohjelmoinnin perusteet Y Python

C++11 lambdat: [](){} Matti Rintala

Toinen harjoitustyö. ASCII-grafiikkaa 2017

Ohjelmoinnin perusteet Y Python

Esimerkkiprojekti. Mallivastauksen löydät Wroxin www-sivuilta. Kenttä Tyyppi Max.pituus Rajoitukset/Kommentit

Transkriptio:

TIE-20100 Tietorakenteet ja algoritmit, kevät 2017 Harjoitustyö 3: It's a social network, baby! Viimeksi päivitetty 11.04.2017 Huom. koska tämä harjoitustyö pohjautuu aiempaan harjoitustyöhön, on allaolevassa merkitty harmaalla pohjalla kaikki muuttuneet / uudet asiat. Harjoitustyön aihe Kolmannessa harjoitustyössä kahden ensimmäisen harjoitustyön ohjelmaa laajennetaan edelleen niin, että se osaa käsitellä ihmisten välisiä ystävyyssuhteita. Taustatarina: Yritys on huomannut, että sen on silloin tällöin tarpeen manipuloida työntekijöitä levittämällä huhuja. Huhut leviävät parhaiten ystävien kesken, erityisesti jos tilanteeseen liittyy mallasjuomia. Niinpä yritys on alkanut pitää kirjaa työntekijöiden välisistä ystävyyssuhteista ja siitä, kuinka monen tuopin jälkeen huhu leviää ystävältä toiselle (myöhempänä vain "kustannus"). Yksinkertaisuuden vuoksi oletetaan että kahden ystävän välillä kustannus on sama molempiin suuntiin. Ystävyyksien lisäämisen poistamisen lisäksi järjestelmästä halutaan pystyä tekemään seuraavanlaisia hakuja: Ketkä ovat tietyn työntekijän välittömät ystävät, ja mikä kustannus kuhunkin ystävyyteen liittyy. Luettelo kaikista yhtiön työntekijöiden välisistä ystävyyksistä. Mikä on pienin määrä ystävyyksiä (ja pubi-iltoja), jolla huhun saa levitettyä tietyltä työntekijältä tietylle toiselle työntekijälle, ja mikä on kyseisen operaation kokonaiskustannus (siltä varalta, että työnantaja haluaa varmistaa huhun leviämisen tarjoamalla mallasjuomat). Mikä on kokonaiskustannukseltaan halvin reitti saada huhu levitettyä tietyltä työntekijältä tietylle toiselle työntekijälle. Tämä reitti saattaa siis sisältää useampia ystävyyksiä kuin edellinen (ja olla siis hitaampi), mutta se on kustannustehokkain. Jos huhu halutaan levittää koko henkilöstölle, mitä ystävyyksiä pitkin tämä onnistuu kokonaiskustannuksiltaan halvimmalla. Koska ystävyydet eivät välttämättä muodosta yhtä kytkettyä verkostoa, voi olla että tuloksena olevat ystävyydet eivät muodosta yhtä yhtenäistä reitistöä (ja työnantajan täytyy käynnistää huhu usean työntekijän kanssa). Tämä operaatio on toteutettu harjoitustyössä niin, että ystävyysverkostosta poistetaan kaikki ystävyydet, jotka eivät kuulu tähän "kustannusoptimoituun reitistöön". Toisessa harjoitustyössä ensimmäisen harjoitustyön ohjelmaa laajennetaan niin, että se osaa käsitellä myös ihmisten esimiessuhteita ja muutamia muita uusia asioita. Työntekijöiden yksilöiminen tehdään nyt yksikäsitteisen ID-tunnisteen avulla. Ohjelmalla saa myös haettua palkkoihin liittyviä tunnuslukuja, joita ihan oikeastikin käytetään: minimi- ja maksimipalkan,

mediaanipalkan sekä palkkakvartiilit (tunnuslukujen määritelmät löytyvät myöhemmin tästä ohjeesta). (Kiinnostuneille: mediaanit ja kvartiilit kertovat palkoista enemmän kuin keskiarvo ja keskihajonta, koska palkkojen suuruudet ovat yleensä todella epätasaisesti jakautuneita, jolloin esim. pieni määrä miljardöörejä saa keskiarvon nousemaan hämäävän suureksi "normaaleihin" palkkoihin verrattuna). Koska kyseessä on Tietorakenteiden ja algoritmien harjoitustyö, ohjelman tehokkuus on tärkeä arvostelukriteeri. Tavoitteena on tehdä mahdollisimman tehokkas toteutus, kun oletetaan että kaikki ohjelman tuntemat komennot ovat suunnilleen yhtä yleisiä (ellei komentotaulukossa toisin mainita). Plussaa tietysti saa, mitä tehokkaammin operaatiot pystyy toteuttamaan. Huomaa erityisesti seuraavat asiat: Tässä harjoitustyössä testataan ja arvostellaan vain uuteen toiminnallisuuteen liittyvät osat, eli uudet operaatiot ja vanhoista operaatioista ne osat, jotka niihin on lisättävä tai muutettava uuden toiminnallisuuden tukemiseksi. Pääohjelmaa on päivitetty. Kun ohjelman suoritus loppuu, ohjelma tulostaa (cerr:iin) "Program ended normally". Jos tuota ei tulostu, ohjelma on kaatunut. Jos ohjelman ajon aikana on ajettu testread-testejä, ohjelman loppuun tulostetaan myös (cerr:iin), oliko missään testissä havaittu eroja oletetun tulostuksen kanssa. Kolmannessa harjoitustyössä pakollisia uusia operaatioita ovat add_friendship(), all_friendships(), remove_friendship(), get_friends() ja shortest_friendpath(). Operaatioiden check_boss_hierarchy(), cheapest_friendpath() ja leave_cheapest_friendforest() toteuttaminen ei ole pakollista läpipääsyn kannalta. Ne ovat kuitenkin osa arvostelua, joten toteuttamatta jättäminen vaikuttaa työn arvosanaan! Vinkki ei-pakollisten operaatioiden toteuttamiseen. Kurssin pitäjän arvaus on, että check_boss_hierarchy() on helpoin toteuttaa, sitten tulee cheapest_friendpath() ja vaikein on leave_cheapest_friendforest(). Tämän viimeisen operaation osalta joudut itse hieman miettimään ja etsimään sopivaa algoritmia. Sopiva algoritmi tulee kyllä vastaan kurssilla, mutta ei välttämättä luennoilla. Kolmannen harjoitustyön operaatioissa asymptoottiseen tehokkuuteen ei välttämättä pysty hirveästi vaikuttamaan, koska käytetyt algoritmit määräävät sen. Sen vuoksi kolmannessa harjoitustyössä algoritmien toteutukseen ja toiminnallisuuteen kiinnitetään enemmän huomiota kuin tehokkuuteen. Kurssin puolesta tulee kuitenkin tehokkuustestejä, erillinen testi jokaiselle etsintäoperaatiolle. Vihje tehokkuudesta: Jos minkään operaation keskimääräinen tehokkuus on huonompi kuin ϴ(n log n), ratkaisun tehokkkuus ei ole hyvä. Suurin osa operaatioista on mahdollista toteuttaa paljon nopeamminkin. Kolmannen harjoitustyön jotkin operaatiot saattavat pakosti olla hitaampiakin. Osana ohjelman palautusta palautetaan git:ssä dokumentti nimeltä "readme.pdf", jossa perustellaan toteutuksessa käytetyt tietorakenteet tehokkuuden kannalta. Siinä luetellaan myös oma arvio kunkin toteutetun operaation tehokkuudesta O-notaatiolla.

Tätä dokumenttia tarvitsee kolmannen harjoitustyön osalta päivittää vain uusien ja muuttuneiden asioiden osalta. Operaatioiden remove(), nearest_common_boss() ja higher_lower_ranks() toteuttaminen ei ole pakollista läpipääsyn kannalta. Ne ovat kuitenkin osa toisen arvostelua, joten toteuttamatta jättäminen vaikuttaa toisen harjoitustyön arvosanaan! Tehokkuudessa olennaisinta on, miten ohjelman tehokkuus muuttuu datan kasvaessa, eivät pelkät sekuntimäärät. Operaation tehokkuuteen lasketaan kaikki siihen liittyvä työ, myös mahdollisesti alkioiden lisäyksen yhteydessä tehty operaatioon liittyvä työ. Plussaa tietysti saa, jos operaatioita saa toteutettua vaadittua mahdollisimman tehokkasti. Samoin plussaa saa, mitä nopeammaksi operaatiot saa sekunteinakin (jos siis kertaluokka on vähintään vaadittu). Mutta plussaa saa vain tehokkuudesta, joka syntyy omista algoritmivalinnoista ja suunnittelusta. (Esim. kääntäjän optimointivipujen vääntely, rinnakkaisuuden käyttö, häkkerioptimoinnilla kellojaksojen viilaaminen eivät tuo pisteitä.) Riittävän huonolla toteutuksella työ voidaan hylätä. Esimerkkejä kysymyksistä, joilla tehokkuutta voi usein parantaa: Tehdäänkö jokin asia turhaan useaan kertaan? Voiko jonkin asian joskus jättää kokonaan tekemättä? Tehdäänkö joissain työtä enemmän kuin on välttämättä tarpeen? Voiko jonkin asian tehdä "lähes ilmaiseksi" samalla, kun tehdään jotain muuta? Harjoitustyössä käytetyt tunnuslukujen määritelmät Tässä harjoitustyössä palkkojen vertailuissa käytetään seuraavia tunnuslukuja. Harjoitustyön yksinkertaistamiseksi niiden määritelmiä on hieman yksinkertaistettu. Alla "palkkajärjestys" tarkoittaa järjestystä pienimmäistä palkasta suurimpaan. Minimi / maksimi: Henkilö, jolla on pienin/suurin palkka. Jos tällaisia henkilöitä on useita, palautetaan jokin heistä. Mediaani: Palkkajärjestyksessä keskimmäinen henkilö. Tässä harjoitustyössä palkkajärjestyksessä henkilö indeksillä n. ( x on pyöristys alaspäin eli C++:n 2 normaali kokonaislukujakolaskun tapa pyöristää.). Ensimmäinen kvartiili: Palkkajärjestyksessä neljäsosan kohdalla oleva henkilö. Tässä harjoitustyössä palkkajärjestyksessä henkilö indeksillä n 4. Kolmas kvartiili: Palkkajärjestyksessä kolmannen neljäsosan kohdalla oleva henkilö. Tässä harjoitustyössä palkkajärjestyksessä henkilö indeksillä (3n) 4.

Järjestämisestä Työntekijöitä järjestettäessä on mahdollista, että palkan mukaan järjestettäessä usealla on sama palkka (tai nimijärjestyksessä nimi). Tällaisten tapausten keskinäinen järjestys on mielivaltainen. Ohjelman hyväksymissä nimissä voi olla vain kirjaimia A-Z, a-z ja sanavälejä. Järjestämisen voi tehdä joko C++:n string-luokan vertailuoperaattorin "<" mukaan (jossa sanaväli tulee ennen kirjaimia ja isot kirjaimet tulevat ennen pieniä) tai "oikealla tavalla", jossa vastaavat isot ja pienet kirjaimet ovat samanarvoisia, mutta sanaväli tulee edelleen ennen muita kirjaimia. Työntekijöiden ID:iden järjestämisessä tulee käyttää C++:n string-luokan "<"-vertailua. Harjoitustyön toteuttamisesta ja C++:n käytöstä Tämän harjoitustyön tarkoituksena on opetella valmiiden tietorakenteiden ja algoritmien käyttöä, joten C++:n STL:n käyttö on erittäin suotavaa ja osa arvostelua. Mitään erityisiä rajoituksia C++:n standardikirjaston käytössä ei ole. Luonnollisesti kielen ulkopuolisten kirjastojen käyttö ei ole sallittua (esim. Windowsin omat kirjastot tms.). HUOMAA, että koska tämän harjoitustyön tarkoituksena on harjoitella STL:n käyttöä, on erittäin todennäköistä, että ensimmäisen harjoitustyön tietorakenneratkaisusi EI ole paras mahdollinen tässä harjoitustyössä. Samoin kannattaa harkita, missä kohdin ensimmäisessä harjoitustyössä itse toteutettuja algoritmeja voi korvata STL:n valmiilla algoritmeilla! Ohjelman toiminta ja rakenne Osa ohjelmasta tulee valmiina kurssin puolesta, osa toteutetaan itse. Valmiit osat, jotka tarjotaan kurssin puolesta Tiedosto main.cpp (johon EI SAA TEHDÄ MITÄÄN MUUTOKSIA) Pääohjelma, joka hoitaa syötteiden lukemisen, komentojen tulkitsemisen ja tulostusten tulostamisen. Pääohjelmassa on myös valmiina komentoja testaamista varten. Tiedosto datastructure.hpp class Datastructure: Luokka, johon harjoitustyö kirjoitetaan. Luokasta annetaan valmiina sen julkinen rajapinta (johon EI SAA TEHDÄ MITÄÄN MUUTOKSIA) Tyyppimäärittely Salary: kokonaisluku. Määritelty myös vakio NO_SALARY esim. tilanteita varten, joissa palkka ei ole tiedossa Tyyppimäärittely PersonID: merkkijono, joka koostaa numeroista 0-9 ja kirjaimista välillä a-z tai A-Z. Määritelty myös vakio NO_ID, jota käytetään paluuarvona jos henkilöä ei löydy. Tiedosto datastructure.cpp Funktio random_in_range: Ykkösharjoitustyön tapaan arpoo luvun annetulla välillä (alku- ja loppuarvo ovat molemmat välissä mukana).

Harjoitustyönä toteutettavat osat Tiedostot datastructure.hpp ja datastructure.cpp class Datastructure: Luokan julkisen rajapinnan jäsenfunktiot tulee toteuttaa. Luokkaan saa listätä omia määrittelyitä (jäsenmuuttujat, uudet jäsenfunktiot yms.) Huom! Omassa koodissa ei ole tarpeen tehdä ohjelman varsinaiseen toimintaan liittyviä tulostuksia, koska pääohjelma hoitaa ne. Mahdolliset Debug-tulostukset kannattaa tehdä cerr-virtaan, jotta ne eivät sotke testejä. Ohjelman tuntemat komennot ja luokan julkinen rajapinta Kun ohjelma käynnistetään, se näyttää komentokehotteen ">" ja jää odottamaan komentoja, jotka on selitetty alla. Komennot, joiden yhteydessä mainitaan jäsenfunktio, kutsuvat ko. Datastructureluokan operaatioita, jotka siis opiskelijat toteuttavat. Osa komennoista on taas toteutettu kokonaan kurssin puolesta pääohjelmassa. Jos ohjelmalle antaa komentoriviltä tiedoston parametriksi, se lukee komennot ko. tiedostosta ja lopettaa sen jälkeen. Komento Julkinen jäsenfunktio add 'nimi' id 'titteli' palkka void add_person(string name, PersonID id, string title, Salary salary); remove id void remove_person(personid id); add_boss id bossid void add_boss(personid id, PersonID bossid); (no command) string get_name(personid id); (no command) string get_title(personid id); Selitys Lisää tietorakenteeseen työntekijän annetulla nimellä, uniikilla id:llä, tittelillä ja palkalla. Aluksi työntekijälle ei ole esimiestä. Tätä komentoa testataan myös hw3:ssa. Poistaa annetulla ID:llä olevan työntekijän. Jos työntekijää ei ole lisätty, ei tee mitään. Jos poistettavalla työntekijällä on alaisia, alaiset siirtyvät poistetun työntekijän pomon alaisiksi. Jos pomoa ei ole, ei alaisillekaan jää pomoa poiston jälkeen. Jos annetulla ID:llä ei löydy työntekijää, ei tehdä mitään. Kun työntekijä poistetaan, kaikki poistuvat myös kaikki häneen liittyvät ystävyyssuhteet. Tämän komennon toteutus ei ole pakollinen (mutta se vaikuttaa toisen harjoitustyön arvosteluun). Lisää työntekijälle esimiehen. Työntekijälle voi olla vain yksi esimies. Työssä hw3 on mahdollista, että komennolla luodut esimiessuhteet muodostavat silmukoita (ts. työntekijä on suoraan tai epäsuorasti itsensä pomo). Tätä komentoa testataan myös hw3:ssa. Palauttaa annetulla ID:llä olevan työntekijän nimen. (Pääohjelma kutsuu tätä eri paikoissa.) Tätä operaatiota kutsutaan useammin kuin muita.tätä komentoa testataan myös hw3:ssa. Palauttaa annetulla ID:llä olevan työntekijän tittelin. (Pääohjelma kutsuu tätä eri paikoissa.) Tätä operaatiota kutsutaan useammin kuin muita. Tätä komentoa testataan myös hw3:ssa.

Komento Julkinen jäsenfunktio (no command) Salary get_salary(personid id); size unsigned int size(); clear void clear(); find 'name' vector<personid> find_persons(string name); titlelist 'title' vector<personid> personnel_with_title(string title); change_name id 'new name' void change_name(personid id, string new_name); change_salary id newsalary void change_salary(personid id, Salary new_salary); alphalist vector<personid> personnel_alphabetically(); salarylist vector<personid> personnel_salary_order(); min PersonID min_salary(); max PersonID max_salary(); median PersonID median_salary(); 1stquartile PersonID first_quartile_salary(); 3rdquartile PersonID third_quartile_salary(); underlings id vector<personid> underlings(personid id); Selitys Palauttaa annetulla ID:llä olevan työntekijän palkan. (Pääohjelma kutsuu tätä eri paikoissa.) Tätä operaatiota kutsutaan useammin kuin muita. Tätä komentoa testataan myös hw3:ssa. Palauttaa tietorakenteessa olevien työntekijöiden lukumäärän. Tätä komentoa testataan myös hw3:ssa. Tyhjentää tietorakenteen (tämän jälkeen size palauttaa 0). Tätä komentoa testataan myös hw3:ssa. Palauttaa listan henkilöistä, joilla on annettu nimi. Lista on järjestettävä nousevan ID:n mukaiseen järjestykseen. Palauttaa listan henkilöistä, joilla on annettu titteli. Lista on järjestettävä nousevan ID:n mukaiseen järjestykseen. Tätä operaatiota kutsutaan harvoin, eikä se ole mukana tehokkuustestissä. Muuttaa annetulla ID:llä olevan henkilön nimen. Muuttaa annetulla ID:llä olevan henkilön palkan. Palauttaa työntekijät nimen mukaan aakkosjärjestyksessä. Palauttaa työntekijät palkan mukaan suuruusjärjestyksessä (pienin ensin). Palauttaa työntekijän, jolla on pienin palkka (ks. ohjeista minimin määritelmä tässä työssä). Palauttaa työntekijän, jolla on suurin palkka (ks. ohjeista maksimin määritelmä tässä työssä). Palauttaa työntekijän, jolla on mediaanipalkka eli palkkajärjestyksessä keskimmäisen (ks. ohjeista mediaanin määritelmä tässä työssä). Palauttaa työntekijän, jolla on 1. kvartiilipalkka eli palkkajärjestyksessä neljäsosan kohdalla (ks. ohjeista kvartiilien määritelmä tässä työssä). Palauttaa työntekijän, jolla on 3. kvartiilipalkka eli palkkajärjestyksessä kolmen neljäsosan kohdalla (ks. ohjeista kvartiilien määritelmä tässä työssä). Komento tulostaa sisennettynä listan työntekijän alaisista ja heidän alaisistaan. HUOM! Itse jäsenfunktio palauttaa ainoastaan listan työntekijän välittömistä alaisista. Lista on järjestettävä nousevan ID:n mukaiseen järjestykseen. Pääohjelma käyttää jäsenfunktiota rekursiivisesti hierarkian tulostamiseen.

Komento Julkinen jäsenfunktio ceo PersonID find_ceo(); nearest_common_boss id1 id2 PersonID nearest_common_boss(personid id1, PersonID id2); higher_lower_ranks id pair<unsigned int, unsigned int> higher_lower_ranks(personid id); add_friend id friendid cost void add_friendship(personid id, PersonID friendid, Cost cost); remove_friend id friendid void remove_friendship(personid id, PersonID friendid); friends_of id vector<pair<personid, Cost>> get_friends(personid id); all_friendships vector<pair<personid, PersonID>> all_friendships(); Selitys Palauttaa organisaation pääjohtajan (jonka alaisia kaikki suoraan tai epäsuorasti ovat) ja varmistaa, että organisaatiolla on tasan yksi tällainen pääjohtaja. Jos ei ole, palauttaa NO_ID. Tässä operaatiossa saa hw3:ssakin edelleen olettaa, että esimiessuhteet eivät voi muodostaa silmukoita (ts. työntekijä ei voi olla suoraan tai epäsuorasti itsensä pomo). Jos näin ei ole, operaation ei tarvitse tuottaa oikeaa vastausta. Palauttaa kahden työntekijän lähimmän yhteisen esimiehen tai NO_ID, jos sellaista ei ole. Tämän komennon toteutus ei ole pakollinen (mutta se vaikuttaa toisen harjoitustyön arvosteluun). Palauttaa parin, jonka ensimmäinen luku kertoo, kuinka monta tasoltaan suurempaa työntekijää organisaatiohierarkiassa on, ja toinen luku kertoo, kuinka monta pienempää. Pääjohtajan taso on korkein, hänen alaistensa yhtä alempi jne. Jos organisaatio ei muodosta yhtä yksikäsitteistä hierarkiaa, on määrittelemätöntä mitä palautetaan. Tämän komennon toteutus ei ole pakollinen (mutta se vaikuttaa toisen harjoitustyön arvosteluun). Lisää työntekijöiden id ja frienid välille ystävyyden, johon liittyy annettu kustannus. Ystävyys on molemminpuolinen (ja kustannus on kumpaankin suuntaan sama). Jos jompaa kumpaa id:tä ei ole, ei tehdä mitään. Poistaa ystävyyden kahden työntekijän väliltä. Jos ystävyyttä ei ollut alun perinkään tai jompaa kumpaa id:tä ei löydy, ei tehdä mitään. Palauttaa listan annetun työntekijän ystävistä ja ko. ystävyyksiin liittyvistä kustannuksista. Lista on järjestettävä nousevan ID:n mukaiseen järjestykseen. Palauttaa listan kaikista ystävyyksistä. Jokainen ystävyys on listassa vain kerran, ja esitetään siinä järjestyksessä, että ystävyysparin ensimmäinen id on pienempi kuin toinen id. Listassa parit on järjestetty ensisijaisesti ensimmäisen id:n mukaan, toissijaisesti toisen (std::pair:n oletusarvoinen vertailu). Tämän operaation tehokkuutta ei mitata eikä arvostella, se on olemassa debuggausta ja testausta helpottamaan.

Komento Julkinen jäsenfunktio shortest_friendpath vector<pair<personid, Cost>> shortest_friendpath(personid fromid, PersonID toid); check_boss_hierarchy bool check_boss_hierarchy(); cheapest_friendpath vector<pair<personid, Cost>> cheapest_friendpath(personid fromid, PersonID toid); leave_cheapest_friendforest pair<unsigned int, Cost> leave_cheapest_friendforest(); random_friends n random_add n random_seed n Selitys Palauttaa lyhimmän "ystävyysreitin" työntekijästä fromid työntekijään toid. Reitti kertoo, minkä ystävyyksien kautta (ja millä kustannuksella) huhu välittyy henkilöstä toiseen pienimmällä mahdollisella määrällä ystävyyksiä. Paluuarvo sisältää reitin askeleet (henkilö ja henkilöön pääsemisen kustannus edellisestä henkiöstä) oikeassa järjestyksessä. Jos reittiä ei löydy, palautetaan tyhjä lista. Pääohjelma laskee kokonaiskustannuksen. Tarkastaa, että esimieshierarkia muodostaa yhden syklittömän (kukaan ei ole suoraan tai epäsuorasti oma esimiehensä) hierarkian, joka kattaa kaikki työntekijät. Jos näin on, palautetaan true, muuten false. (Tämä siis eroaa find_ceo:sta mm. siinä, että find_ceo olettaa hierarkian syklittömäksi, tämä taas tarkastaa, ettei syklejä ole ja että kaikki työntekijät ovat yhdessä hierarkiassa.) Palauttaa halvimman "ystävyysreitin" työntekijästä toiseen. Reitti kertoo, minkä ystävyyksien kautta (ja millä kustannuksella) henkilöstä toiseen pääsee pienimmällä mahdollisella kokonaiskustannuksella. Paluuarvo sisältää listan henkilöitä ja henkilöihin pääsemisen kustannuksen kullakin askeleella. Jos reittiä ei löydy, palautetaan tyhjä lista. Pääohjelma laskee kokonaiskustannuksen. Jättää jäljelle ystävyydet, joilla voidaan saavuttaa kaikki työntekijät, ja joiden yhteenlaskettu kustannus on mahdollisimman pieni. Jos ystävyydet eivät muodosta yhtä yhtenäistä (kytkettyä) verkostoa, tehdään sama kaikille erillisille verkoston osille. Muut ystävyydet poistetaan. Paluuarvo kertoo, montako yhtenäistä (kytkettyä) osaa ystävyyksissä oli, ja mikä on jäljelle jääneiden ystävyyksien kokonaiskustannus. Lisää henkilöiden välille annetun määrän satunnaisia ystävyyksiä satunnaisilla kustannuksilla. Lisää tietorakenteeseen (testausta varten) n kpl työntekijöitä, joilla on satunnainen id, nimi, tittleli ja palkka, ja jokaiselle satunnaisen pomon. Huom! Arvot ovat tosiaan satunnaisia, eli saattavat olla kerrasta toiseen eri. Tämä komento ei lisää ystäviä. Asettaa pääohjelman satunnaislukugeneraattorille uuden siemenarvon. Oletuksena generaattori alustetaan joka kerta eri arvoon, eli satunnainendata on eri ajokerroilla erilaista. Siemenarvon asettamalla arvotun datan saa toistumaan samanlaisena kerrasta toiseen (voi olla hyödyllista debuggaamisessa).

Komento Julkinen jäsenfunktio read 'tiedostonimi' stopwatch on / off / next Tätä kartoitusta tarvitaan monesta syystä: perftest all/compulsory/cmd1;cmd2... timeout n friendcount n1;n2;n3... testread 'in-tiedostonimi' 'out-tiedostonimi' help quit Selitys Lukee lisää komentoja annetusta tiedostosta. (Tällä voi esim. lukea listan tiedostossa olevia työntekijöitä tietorakenteeseen, ajaa valmiita testejä yms.) Aloittaa tai lopettaa komentojen ajanmittauksen. Ohjelman alussa mittaus on pois päältä ("off"). Kun mittaus on päällä ("on"), tulostetaan jokaisen komennon jälkeen siihen kulunut aika. Vaihtoehto "next" kytkee mittauksen päälle vain seuraavan komennon ajaksi (kätevää read-komennon kanssa, kun halutaan mitata vain komentotiedoston kokonaisaika). Ajaa ohjelmalle tehokkuustestit. Tyhjentää tietorakenteen ja lisää sinne n1 kpl satunnaisia työntekijöitä ja jokaiselle 0-friendcount kpl ystäviä satunnaisella kustannuksella. Sen jälkeen arpoo n kertaa satunnaisen komennon. Mittaa ja tulostaa sekä lisäämiseen että komentoihin menneen ajan. Sen jälkeen sama toistetaan n2:lle jne. Jos jonkin testikierroksen suoritusaika ylittää timeout sekuntia, keskeytetään testien ajaminen (tämä ei välttämättä ole mikään ongelma, vaan mielivaltainen aikaraja). Jos ensimmäinen parametri on all, arvotaan lisäyksen jälkeen kaikkista komennoista. Jos se on compulsory, testataan vain komentoja, jotka on pakko toteuttaa. Jos parametri on lista komentoja, arvotaan komento näiden joukosta (tällöin kannattaa mukaan ottaa myös random_add ja random_friends, jotta lisäyksiä tulee myös testikierroksen aikana). Ajaa toiminnallisuustestin ja vertailee tulostuksia. Lukee komennot tiedostosta in-tiedostonimi ja näyttää ohjelman tulostuksen rinnakkain tiedoston outtiedostonimi sisällön kanssa. Jokainen eroava rivi merkitään kysymysmerkillä, ja lopuksi tulostetaan vielä tieto, oliko eroavia rivejä. Tulostaa listan tunnetuista komennoista. Lopettaa ohjelman. (Tiedostosta luettaessa lopettaa vain ko. tiedoston lukemisen.) "Datatiedostot" Kätevin tapa testata ohjelmaa on luoda "datatiedostoja", jotka add-komennolla lisäävät joukon työntekijöitä ohjelmaan. Työntekijät voi sitten kätevästi lukea sisään tiedostosta read-komennolla ja sitten kokeilla muita komentoja ilman, että työntekijät täytyisi joka kerta syöttää sisään käsin. Alla on esimerkki datatiedostosta, joka löytyy nimellä example-data.txt:

# Adding people add 'Meikkis Matti' mm 'basic worker' 2000 add 'Teikkis Terttu' tt 'technical evangelist' 4000 add 'Miljoona Miikka' richbastard 'commander' 1000000 add 'Sorrettu Sami' doesall 'general utility' 1 add 'Keskiverto Keijo' kk1 'basic worker' 3000 add 'Kukalie Kirsi' kk2 'basic worker' 2500 add 'Olematon Oskari' nobody 'useless' 6000 # Adding boss relationships add_boss mm richbastard add_boss doesall mm add_boss nobody mm add_boss tt richbastard add_boss kk1 tt add_boss kk2 tt # Add friendships add_friend doesall nobody 1 add_friend mm doesall 3 add_friend tt mm 5 add_friend tt kk2 2 add_friend kk1 nobody 1 add_friend kk2 kk1 2 add_friend kk2 mm 4 add_friend richbastard mm 8 add_friend richbastard tt 2 Esimerkki ohjelman toiminnasta Alla on esimerkki ohjelman toiminnasta. Esimerkin syöte löytyy tiedostosta example-in.txt ja alla oleva tulostus tiedostosta example-out.txt. Eli voit testata esimerkin toimimista käynnistämällä ohjelman ja antamalla komennon testread 'example-in.txt' 'example-out.txt'. > clear Cleared all persons > size Number of employees: 0 > read 'example-data.txt' ** Commands from 'example-data.txt' > # Adding people > add 'Meikkis Matti' mm 'basic worker' 2000 > add 'Teikkis Terttu' tt 'technical evangelist' 4000 > add 'Miljoona Miikka' richbastard 'commander' 1000000 > add 'Sorrettu Sami' doesall 'general utility' 1 > add 'Keskiverto Keijo' kk1 'basic worker' 3000 > add 'Kukalie Kirsi' kk2 'basic worker' 2500 > add 'Olematon Oskari' nobody 'useless' 6000 > # Adding boss relationships > add_boss mm richbastard > add_boss doesall mm > add_boss nobody mm > add_boss tt richbastard > add_boss kk1 tt > add_boss kk2 tt

> # Add friendships > add_friend doesall nobody 1 > add_friend mm doesall 3 > add_friend tt mm 5 > add_friend tt kk2 2 > add_friend kk1 nobody 1 > add_friend kk2 kk1 2 > add_friend kk2 mm 4 > add_friend richbastard mm 8 > add_friend richbastard tt 2 > ** End of commands from 'example-data.txt' > size Number of employees: 7 > all_friendships doesall - mm doesall - nobody kk1 - kk2 kk1 - nobody kk2 - mm kk2 - tt mm - richbastard mm - tt richbastard - tt > friends_of tt id kk2 : basic worker Kukalie Kirsi, salary 2500 (cost 2) id mm : basic worker Meikkis Matti, salary 2000 (cost 5) id richbastard : commander Miljoona Miikka, salary 1000000 (cost 2) > friends_of mm id doesall : general utility Sorrettu Sami, salary 1 (cost 3) id kk2 : basic worker Kukalie Kirsi, salary 2500 (cost 4) id richbastard : commander Miljoona Miikka, salary 1000000 (cost 8) id tt : technical evangelist Teikkis Terttu, salary 4000 (cost 5) > remove_friend tt mm > friends_of tt id kk2 : basic worker Kukalie Kirsi, salary 2500 (cost 2) id richbastard : commander Miljoona Miikka, salary 1000000 (cost 2) > friends_of mm id doesall : general utility Sorrettu Sami, salary 1 (cost 3) id kk2 : basic worker Kukalie Kirsi, salary 2500 (cost 4) id richbastard : commander Miljoona Miikka, salary 1000000 (cost 8) > shortest_friendpath richbastard nobody Shortest path of friends is: id mm : basic worker Meikkis Matti, salary 2000 (cost 8) id doesall : general utility Sorrettu Sami, salary 1 (cost 3) id nobody : useless Olematon Oskari, salary 6000 (cost 1) Total cost is 12 > cheapest_friendpath richbastard nobody Cheapest path of friends is:

id tt : technical evangelist Teikkis Terttu, salary 4000 ( cost2) id kk2 : basic worker Kukalie Kirsi, salary 2500 ( cost2) id kk1 : basic worker Keskiverto Keijo, salary 3000 ( cost2) id nobody : useless Olematon Oskari, salary 6000 ( cost1) Total cost is 7 > leave_cheapest_friendforest Remaining friend forest has 1 trees with the total cost of 11 > all_friendships doesall - mm doesall - nobody kk1 - kk2 kk1 - nobody kk2 - tt richbastard - tt > check_boss_hierarchy Boss hierarchy is ok. > add 'Me' me 'great' 1000 > add 'You' you 'sucker' 1 > add_boss me you > add_boss you me > check_boss_hierarchy Boss hierarchy is broken. > quit