Vse o Računalništvu 1 (2021/22)

Odgovori na vprašanja s predstavitev Kratkih vprašanj

Odgovori na vprašanja s predstavitev Kratkih vprašanj

od Matija Lokar -
Število odgovorov: 175

Potem ko dobite "ocenjevalne liste", odprite "podtemo" te teme, ki ima kot naslov vaš priimek in kratek naslov vprašanja. V tej podtemi navedite sam problem, potem pa kot podteme napišite vprašanja in vaše odgovore nanje. 

Pričakujem, da boste ostali tu zastavili še kakšno podvprašanje, komentirali odgovor, skratka, da se boste pogovarjali o slišanem!


V odgovor na Matija Lokar

Re: Odgovori na vprašanja s predstavitev Kratkih vprašanj

od Tit Arnšek -
V forumu naredimo novo temo ali naredimo to kot odgovor na zgornje sporočilo?
V odgovor na Tit Arnšek

Re: Odgovori na vprašanja s predstavitev Kratkih vprašanj

od Matija Lokar -
Najbolje kot odgovor na zgornje sporočilo s tem, da seveda spremenite "Zadevo".
V odgovor na Matija Lokar

Arnšek: Najmanjši element v skladu.

od Tit Arnšek -

Algoritem,  ki po vsaki operaciji v skladu (vstavi/odstrani) poišče najmanjše število.


V odgovor na Tit Arnšek

Časovna zahtevnost algoritma?

od Tit Arnšek -

Algoritem je zahtevnosti O(1). To zato, ker vedno, ko želimo poiskati najmanjše število, zgolj pogledamo najvišje število v pomožnem skladu.


V odgovor na Tit Arnšek

Če iz sklada odstranimo vsa števila, ali se tudi avtomatsko vse odstrani iz pomožnega sklada?

od Tit Arnšek -

Ja, zakaj? Vsak element v pomožnem skladu se nahaja tudi v glavnem. Ko odstranimo element iz glavnega sklada, hkrati tudi odstranimo element iz pomožnega sklada, če je le ta enak tistemu iz glavnega.


V odgovor na Tit Arnšek

Bi princip deloval isto, tudi če bi iskali največje število v skladu?

od Tit Arnšek -

Ja, algoritem bi bil popolnoma enak, le da bi v pomožni sklad dodajali vedno večja/ enako velika števila (in ne vedno manjša/enako velika).


V odgovor na Tit Arnšek

Kakšni bi bili testi, robni problemi pri danem algoritmu, ki si ga predstavil?

od Tit Arnšek -

·         V primerih, kjer je sklad prazen, mora algoritem vrniti napako. (Podobno, če bi iskali minimalni element od prazne množice -> vrne napako)

>>> sklad = SkladMin()

>>> print(sklad.min())

ValueError: VRH: Sklad je prazen

·         Podobno tudi tukaj:

>>> sklad = SkladMin()

>>> sklad.vstavi(5)

>>> sklad.odstrani()

>>> print(sklad.min())

ValueError: VRH: Sklad je prazen

 

·         Nato bi dodal še nekaj 'navadnih' primerov (da bi preverjal pravilno sprotno delovanje algoritma, bi rešitve po vsakem koraku shranjeval v neko tabelo; verjetno obstaja veliko bolj pametna metoda 😊):

>>> tabela_minimumov = []

>>> sklad = SkladMin()

>>> sklad.vstavi(5)

>>> tabela_minimumov.append(sklad.min()) 

>>> sklad.vstavi(4)

>>> tabela_minimumov.append(sklad.min())

>>> sklad.vstavi(6)

>>> tabela_minimumov.append(sklad.min())

>>> sklad.vstavi(3)

>>> tabela_minimumov.append(sklad.min())

>>> sklad.vstavi(4)

>>> tabela_minimumov.append(sklad.min())

>>> sklad.odstrani()

>>> tabela_minimumov.append(sklad.min())       

>>> sklad.odstrani()

>>> tabela_minimumov.append(sklad.min())

>>> print(tabela_minimumov)

[5, 4, 4, 3, 3, 3, 4]


V odgovor na Tit Arnšek

Kako bi enako stvar naredil za vrsto?

od Tit Arnšek -

Tukaj je algoritem nekoliko drugačen. Eden izmed 'pametnih' načinov je, da uporabimo pomožno vrsto, kjer število vedno vstavimo noter. Tukaj je razlika v tem, da vsa števila, ki so večja od tistega, ki ga vstavimo v pomožni sklad, izbrišemo iz pomožnega sklada. Najmanjši element, je vedno na začetku pomožne vrste. Več si lahko ogledaš na: https://www.geeksforgeeks.org/design-a-queue-data-structure-to-get-minimum-or-maximum-in-o1-time/.


V odgovor na Tit Arnšek

Re: Kako bi enako stvar naredil za vrsto?

od Tit Arnšek -
Napaka**: Tukaj je razlika v tem, da vsa števila, ki so večja od tistega, ki ga vstavimo v pomožno vrsto*, izbrišemo iz pomožne vrste*.
V odgovor na Matija Lokar

Randl: Kako odstraniti srednji element sklada?

od Damijan Randl -

Problem: Poiskati algoritem, ki odstrani srednji element sklada. 

V odgovor na Damijan Randl

Kako dobimo velikost sklada brez uporabe drugega sklada?

od Damijan Randl -

En od možnih načinov je tak, kot sem ga omenil na koncu predstavitve (2. način izboljšave algoritma) in sicer z uporabo rekurzije. Saj nam je tisti algoritem vračal ravno velikost sklada. Je pa res da pri tem posredno vseeno uporabimo pomožen sklad, saj ga ustvari rekurzija sama.


V odgovor na Damijan Randl

Ali res z uporabo rekurzije dovolj zboljšamo časovno zahtevnos algoritma?

od Damijan Randl -

Z uporabo rekurzije ne izboljšamo časovne zahtevnosti algoritma. Predstavljen algoritem je le nek drugačen (mogoče nekoliko bolj eleganten) način, s katerim pridemo do željenega rezultata.  


V odgovor na Damijan Randl

Zakaj smo prevzeli, da pri skladu s sodim številom elementov, npr.4 odstranimo drugi element? gre zgolj za tvojo odločitev ali?

od Damijan Randl -

Da, gre za mojo odločitev predvsem zaradi lažje predstavitve, saj lahko v tem primeru uporabimo kar celostevilsko deljenje (ali pa si pomagamo z int() – kot sem si jaz). Če pa bi hoteli odstraniti 3. element, bi si lahko pri pogoju pomagali z ukazom math.ceil(velikost/2 – 1).


V odgovor na Damijan Randl

V katerih primerih, ko iščemo srednji element, uporabimo sklad, namesto recimo seznama?

od Damijan Randl -

Mislim, da sklada in seznama med sabo nemoremo neposredno primerjati. Saj je sklad podatkovna struktura, ki pa jo lahko predstavimo tudi s npr. seznamom. 


V odgovor na Damijan Randl

Kateri element odstranimo, če je število elementov sodo? nižjega v skladu?

od Damijan Randl -

Tako je, s tem algoritmom odstranimo nižji element v skladu oz. element ki je bil prej vstavljen v sklad.


V odgovor na Damijan Randl

V primeru sklada s sodim številom elementov, ali bi lahko odstranili tisti drugi element (npr. če sta v sredini 3 in 5, in si ti povedal da bomo odstranili 5, a bi se dalo namesto 5 odstraniti 3?

od Damijan Randl -

Da, lahko bi. Več o tem pa sem napisal pri podobnem vprašanju zgoraj.


V odgovor na Damijan Randl

Koliko časa si potreboval, da si vse pripravil?

od Damijan Randl -

Približno en teden. Od tega 1 – 2 dni bolj intenzivnega dela (ostalo pa so bili bolj popravki, priprava na predstavitev...🙂)


V odgovor na Damijan Randl

Ali misliš da je delo s skladi za ta problem boljše kot naprimer s tabelami (v pythonu)?

od Damijan Randl -

Kot sem omenil že pri podobnem vprašanju, težko primerjamo delo s skladi in s tabelami. Vsekakor bi bilo lažje (verjetno tudi hitrejše) uporabiti kar tabelo oz. seznam v Pythonu in odstraniti srednji element. Če pa smo omejeni le na metode, ki smo jih definirali pri skladu, to seveda ne pride v poštev.


V odgovor na Damijan Randl

Ali bi bilo boljše/slabše če bi pri sodih skladih odstranil oba srednja elementa?

od Damijan Randl -

Algoritem bi bil vsekakor nekoliko bolj zapleten, saj bi potreboval dodaten pogojni stavek. Lahko pa bi enostavno dodali novo funkcijo, ki v primeru, da je število elementov sodo, ta isti algoritem požene dvakrat. Saj v tem primeru izbrišemo oba srednja elementa.


V odgovor na Matija Lokar

Marinković: Prešteti pare iz dveh verižnih seznamov.

od Marko Marinković -

Kako prešteti pare iz dveh danih verižnih seznamov, katerih vsota je enaka neki dani vrednosti.

V odgovor na Marko Marinković

• Ali predpostavimo da imamo opravka samo s pozitivnimi števili?

od Marko Marinković -

Ne, v prikazanem primeru so slučajno bila samo pozitivna števila, funkciji bi delali tudi z negativnimi števili.

V odgovor na Marko Marinković

Prostorska zahtevnost?

od Marko Marinković -

Pri prvi funkciji je O(1), saj si shranjujemo samo število parov in trenutna vozla kjer se nahajamo, pri drugi pa O(n), saj si vsa števila prvega verižnega seznama shranimo v množico/tabelo. Bolje je, da je množica/tabela ustvarjena iz verižnega seznama z manjšo dolžino, da zmanjšamo zavzeti prostor.

V odgovor na Marko Marinković

Ali je linearna zahtevnost najbolj optimalna?

od Marko Marinković -

Mislim, da rešitve nebi mogli izboljšati, saj se v vsakem primeru moramo sprehoditi čez oba verižna seznama.

V odgovor na Marko Marinković

Kakšna bi bila zahtevnost, če bi pare lahko dobili tudi z odštevanjem?

od Marko Marinković -

Časovna zahtevnost se ne spremeni, saj v drugi zanki samo dodamo dodaten pogoj.

V odgovor na Marko Marinković

Če bi namesto v verižnih seznamih iskal pare vsot v vrstah, bi se algoritem sploh kaj spremenil?

od Marko Marinković -

Problem je, da se po vrsti ne moremo sprehoditi brez da jo spreminjamo, kot se lahko v verižnih seznamih. Če nas po algoritmu vrsta več ne zanima, se algoritem nebi spremenil, če pa želimo vrsto ohraniti nespremenjeno, bi pa to morali narediti s pomočjo »stražarja«.

V odgovor na Marko Marinković

Ali bi problem lahko rešili tudi z drugo podatkovno strukturo?

od Marko Marinković -

Za vrsto sem že odgovoril pri prejšnjem vprašanju, za sklad je pa zelo podobno, če bi želeli sklad ohraniti, bi morali to narediti s pomožnim skladom.

V odgovor na Marko Marinković

V kakšnem primeru misliš, da bi lahko uporabili ta algoritem?

od Marko Marinković -

Ta algoritem bi lahko uporabili kadarkoli, ko bi iskali pare, kakršnekoli oblike, iz dveh verižnih seznamov.

V odgovor na Marko Marinković

Ali bi bilo mogoče rešitev izboljšati, če ne bi delali z verižnimi seznami?

od Marko Marinković -

Mislim, da rešitve nebi mogli izboljšati, saj se v vsakem primeru moramo sprehoditi čez oba verižna seznama/sklada/vrsti. Izboljšamo lahko le, če točno vemo s kakšnimi podatki imamo opravka, npr. z urejenimi po velikosti.

V odgovor na Matija Lokar

Tratnik: Razbivanje na podtabele.

od Tomaž Tratnik -

Algoritem, ki tabelo pozitivnih celih števil dolžine n razbije na k podtabel, tako da je maksimalna vsota v podtabeli čim manjša.

V odgovor na Tomaž Tratnik

Ali bi se dalo bisekcijo definirati rekurzivno ter ali bi to naredilo problem hitreje rešljiv?

od Tomaž Tratnik -

Lahko, in sicer takole:

{

def bisekcija_rekurzija(tabela_stevil, k, zacetek = None, konec = None):

    if zacetek == None: #definiramo interval pri prvemu klicu

        zacetek = max(tabela_stevil)

        konec = sum(tabela_stevil)

    

    if zacetek > konec: #zaustavitveni pogoj, ki je bil prej v pogoju while zanke

        return float('inf')

    

    #enako kot prej izračunamo najmanjše število delitev, da je maksimalna vsota namjša ali enaka sredini

    sredina = (zacetek + konec) // 2

    vsota = 0

    stevec = 1

    for i in range(len(tabela_stevil)):

        if vsota + tabela_stevil[i] > sredina:

            stevec += 1

            vsota = tabela_stevil[i]

        else:

            vsota += tabela_stevil[i]

    

    #namesto da spremenimo interval in gremo naprej v zanki, rekurzivno pokličemo funkcijo s spremenjenim intervalom

    if stevec <= k:

        odgovor = min(sredina, bisekcija_rekurzija(tabela_stevil, k, zacetek, sredina - 1))

    else:

        odgovor = bisekcija_rekurzija(tabela_stevil, k, sredina + 1, konec)

    return odgovor

}


Hitrost reševanja se pa ne spremeni, saj s tem nismo nič zmanjšali števila operacij, samo namesto while zanke smo uporabili rekurzijo.

V odgovor na Tomaž Tratnik

Kaj se zgodi če k nastavimo na dolžino tabele ali še več?

od Tomaž Tratnik -

Če nastavimo k na dolžino tabele vrne algoritem največji element v tabeli, saj je to najmanjša maksimalna podvsota.

V primeru, da je k večji, bo algoritem vrnil isti odgovor, vendar to ni smiselno vprašanje, saj tabele ne moremo

razdeliti na več podtabel, kot je elementov.


V odgovor na Tomaž Tratnik

Kolikšna je časovna zahtevnost za 1. način, ki si ga omenil tj. da bi pogledali vse možne kombinacije tabel in potem primerjali vsote, ter za 2. način tj. bisekcija.

od Tomaž Tratnik -

Časovna zahtevnost iskanja vseh možnosti je enaka O((n−1)c(k−1)), kjer c predstavlja število vseh kombinacij, katerih je(n - 1)! / ((n - k)! * (k - 1)!). Časovna zahtevnost bisekcija pa je O(n log(sum)). n predstavlja število elementov v tabeli, k število podtabel in sum vsoto vseh elementov v tabeli.

V odgovor na Tomaž Tratnik

Če bi moral problem rešiti s podatkovno strukturo, katero bi uporabil?

od Tomaž Tratnik -

Za reševanje tega problema ni smiselno uporabljati katerekoli posebne podatkovne strukture, saj ni treba hraniti večjega števila podatkov.

V odgovor na Tomaž Tratnik

Ali bi se časovna zahtevnost spremenila, če bi namesto v tabeli iskal vsote v vrsti?

od Tomaž Tratnik -

Časovna zahtevnost bi bila še vedno O(n log(sum)), bi pa porabili več časa, saj ko bi iskali najmanjšo delitev vrste, da je maksimalna vsota podvrste enaka sredini, bi med tem, ko gremo čez vse elemente v vrsti te elemente shranjevati v pomožno vrsto, nato pa bi jih morali še spraviti nazaj v prvotno vrsto.

V odgovor na Tomaž Tratnik

Ali je nujno da maksimalni element gre na sredino, ali pa obstaja še kakšen drug način?

od Tomaž Tratnik -

Ne vem točno, kaj je mišljeno s tem vprašanjem.

Mi vemo, da je naš odgovor nekje med začetkom in koncom. Nato se vprašamo, na koliko podtabel moramo razdeliti tabelo, da je maksimalna vsota manjša ali enaka sredini. Če je število podtabel manjše ali enako podani, vemo, da je maksimalna vsota manjša ali enaka sredini, zato nastavimo odgovor na sredino in se z istim postopkom vprašamo, če je odgovor mogoče  med sredino in začetkom. Če ne pa se vprašamo, kje med sredino in koncom je odgovor.

V odgovor na Matija Lokar

Toplak: Misliš, da bi bilo iskanje rešitve lažje ali težje, če graf ne bi imel usmerjene povezave?

od Luka Toplak -

Implementacija rešitve se ne bi spremenila veliko, bi se pa spremenila časovna zahtevnost. Pri usmerjenem grafu je bila $ \mathcal{O} \left( (\max_{v \in V(G)} \text{outdeg}(v))^m \right) $, pri neusmerjenem pa $ \mathcal{O} \left( (\max_{v \in V(G)} \text{deg}(v))^m \right) $, kjer je $ \text{outdeg}(v) $ število vseh povezav, ki potekajo iz vozlišča $ v $. To bi za usmerjen in neusmerjen graf z enako strukturo pomenilo, da bo število karakterističnih operacij pri usmerjenem manjše ali enako kot pri neusmerjenem grafu.


V odgovor na Luka Toplak

Ali kdaj algoritem ne bi prišel v poštev?

od Luka Toplak -

Rešitev ne bi bila primerna za velike $ m $ (dolžina poti) ter za grafe, ki so gosto prepleteni s povezavami(npr. vsako vozlišče je povezano z vsemi ostalimi v grafu).


V odgovor na Luka Toplak

Kako bi rešil svojo nalogo za zelo velik m?

od Luka Toplak -

Če bi želeli a problem rešiti za velik $ m $ bi bilo treba graf analizirati, da vidimo kje so povezave z negativno vrednostijo. Ko vemo, največ koliko lahko trenutna cena pade med potjo do končnega vozlišča, vemo tudi kdaj lahko iskanje po trenutni poti predčasno ustavimo. Menim, da bi ta optimizacija prinesla največ k znižanju povprečne časovne zahtevnosti. 

V odgovor na Luka Toplak

Ali obstaja tudi bolj časovno optimalen algoritem za rešitev problema?

od Luka Toplak -

Za problem, ki je zastavljen ne vidim boljše rešitve. Seveda bi lahko uvedli optimizacije, ki v povprečju zmanjšajo število operacij, a časovna zahtevnost v najslabšem primeru bi ostala enaka.

V odgovor na Luka Toplak

Zakaj bi iskali neko pot z točno določenimi števili povezav? Bolje bi bilo isakti samo najcenejšo pot neodvisno od število korakov.

od Luka Toplak -

Pot s točno določenim številom povezav iščemo, ker je bil tako zastavljen problem, sicer pa v praksi ni smiselno fiksirati števila povezav pri problemu najcenejše poti.


V odgovor na Luka Toplak

Kaj se zgodi, če ni mogoče priti od začetnega vozlišča o končnega v m povezavah?

od Luka Toplak -

V tem primeru bo algoritem vrnil $ \infty $, kar si lahko razložimo, tako da za pot med dvema nedosegljivima vozliščema potrebujemo neskončno sredstev.

V odgovor na Luka Toplak

Ali je drugi algoritem časovno bolj zahteven kot prvi?

od Luka Toplak -

Časovna zahtevnost(v najslabšem primeru) je pri obeh rešitvah enaka, ampak bo v povprečju prva rešitev hitrejša, saj ni potrebno iskati poti po povezavah, ki smo jih že prečkali.

V odgovor na Luka Toplak

A v prvi rešitvi v bistvu iščemo drevesno rešitev, torej ne dovoljujemo ciklov?

od Luka Toplak -

Ne, saj lahko pri obeh rešitvah obiščemo isto vozlišče poljubno mnogokrat, kar lahko tvori cikel.

V odgovor na Luka Toplak

Ali se spomniš še kakšmega zanimivega primera?

od Luka Toplak -

Zanimiv primer bi bil graf s ciklom, v katerem bi imele vse povezave negativno ceno. Rešitev, ki lahko prepotuje iste povezve večkat, bi najverjetneje, pri velikem $ m $, ta cikel uporabila za znižanje cene, tako da nekajkrat zaokroži po njem.

V odgovor na Luka Toplak

Ali bi lahko na malo bolj natančen način opisal kako bi pospešil algoritem?

od Luka Toplak -

Ideja je, da bi kot argument imeli tudi slovar, v katerem bi kot ključe hranili pare $ (m,voz) $, kot vrednosti pa ceno od trenutnega do končnega vozlišča z $ m $ povezavami. Tako bi lahko vsakič, ko se vrnemo iz rekurzivnega kilca lahko dodali izračunano vrednost v ta slovar. To bi lahko uporabili, tako da bi ob vstopu v nov rekurzivni klic preverili, če je par $ (trenutniM,trenutnoVoz) $ v slovarju. Če bi bil, lahko vrnemo ceno iz slovarja ter prekinimo iskaje po tisti poti.

V odgovor na Luka Toplak

Ali je možno, da imamo le eno vozlišče?

od Luka Toplak -

V primeru, da je v grafu le eno vozlišče, bo cena najcenejše poti $ \infty $, razena, ko je $ m = 0 $. Takrat bo cena enaka 0.  

V odgovor na Luka Toplak

Se bi dalo mogoče spremenit algoritem, da če bi našel povezavo z neko vrednostjo in potem bi delal drugo povezavo, da takoj ko bi prišel prek trenutnega minimuma bi prekinil s to vejo iskanja?

od Luka Toplak -

Ta ideja bi delovala, če bi za ceno povezav veljala nenegativnost. V predstavljenem problemu pa se lahko zgodi, da je nekje blizu končnega vozlišča povezava, ki je negativana, a po absolutni vrednosti zelo velika. Če bi pred tem odkrili neko slabo pot do končnega vozlišča, bi se lahko zgodilo, da nikoli ne odkrijemo te idealne povezave z nizko ceno, saj bi prej nehali iskati.

V odgovor na Luka Toplak

Primer uporabe?

od Luka Toplak -

Primera uporabe za ta algoritem ne vidim, saj je fiksiranje $ m $ zelo nenevadna zahteva. Problem pa je zelo podoben iskanju najcenejše ali najkrajše poti v splošnem. Trenutni rešitvi za te probleme iz časovne zahtevnosti ne bi bili primerni.


V odgovor na Matija Lokar

Koren: Kako so podani vhodni podatki, torej matrika pomaranč?

od Klavdija Koren -

V matriki so vrednosti 0,1 in 2. 0 predstavlja prazno celico, 1 predstavlja svežo pomarančo, 2 pa gnilo pomarančo.

V odgovor na Klavdija Koren

Ali se v vrsti shranjujejo indeksi gnilih pomaranč kot par iz matrike?

od Klavdija Koren -

Ja, v vrsti se shranjujejo indeksi elementov iz matrike kot pari oblike (i, j), kjer i prestavlja i-to vrstico matrike, j pa j-ti stolpec matrike, ki sem jo poimenovala "košara".

V odgovor na Klavdija Koren

Obstaja mogoče kakšen drug način hranjenja podatkov (namesto matrike)?

od Klavdija Koren -

Verjetno obstaja, vendar se mi zdi, da je najlažje pregledati "mrežo" podatkov s pomočjo matrike, saj morajo biti podatki v "2-dimenzionalnem prostoru", da lahko pogledamo sosednje celice.

V odgovor na Klavdija Koren

Ali bi bil problem, če bi bile v košari samo gnile ali samo sveže pomaranče?

od Klavdija Koren -

Ne, če bi bile v košari samo gnile pomaranče, nam algoritem vrne "Minimalno število korakov, da zgnijejo vse pomaranče = 0", saj so gnile že vse in ne potrebujemo dodatnih korakov. Če bi bile v košari samo sveže pomaranče, nam algoritem vrne "Vse pomaranče ne morejo zgniti", ker nimamo nobene gnile, svežih pa celo košaro. Uporabila sem if stavek in sicer if vrsta.prazna(), nato pa še en if stavek in sicer if sveze == 0 da se prepričamo da ni košara prazna ampak da so v košari le sveže pomaranče. Če pa je vrsta prazna in svežih pomaranč ni, nam algoritem vrne "Košara je prazna".

V odgovor na Klavdija Koren

Ali bi se rešitev dalo izboljšati?

od Klavdija Koren -

https://www.geeksforgeeks.org/minimum-time-required-so-that-all-oranges-become-rotten/

Na danem linku je opisan algoritem, katerega sem uporabila za glavni vir. Pri rešitvi si pomagajo s podobno strukturo kot je vrsta in sicer QUEUE (https://docs.python.org/3/library/queue.html). Deluje podobno, le da ima vgrajene funkcije kot so append, pop, put, get, ... S pomočjo vstavljanja strukture queue bi blo verjetno lažje, a sem želela vključiti vrsto, kot smo jo definirali na predavanjih in vajah.

V odgovor na Klavdija Koren

Ali se lahko izognemo preštevanju elementov v matriki v vsakem koraku?

od Klavdija Koren -

Vse elemente v matriki pregledamo le na začetku. Kasneje gledamo le še sosede gnilih pomaranč. Mislim pa, da se bi temu težko izognili, ker potrebujemo vsaj začetno stanje košare, tako da se enkrat vsaj moramo sprehoditi čez vse elemente. Morda le, če začetni pogoji ne bi bili shranjeni v matriki.

V odgovor na Klavdija Koren

Se lahko zgodi, da so vse pomaranče sveže in ni nobene gnile?

od Klavdija Koren -

Lahko, kot sem že zgoraj napisala, bi v tem primeru dobili rezultat oblike "Vse pomaranče ne morejo zgniti."

V odgovor na Klavdija Koren

Kakšna je zahtevnost pri prvi ideji?

od Klavdija Koren -

Časovna zahtevnost: O((V*S)*(V*S))

  • V je število vrstic
  • S je število stolpcev
  • matrika mora biti pregledana dokler ni nobenih sprememb, to se zgodi max(V*S)/2-krat

Prostorska zahtevnost: O(1)

  • Ne potrebujemo dodatnega prostora za shranjevanje


V odgovor na Klavdija Koren

Kakšna je časovna zahtevnost opisanega algoritma?

od Klavdija Koren -

Mislim, da je časovna zahtevnost O(V*S), da na začetku pregledaš celo matriko, čas ki ga potrebujemo da zgnijejo vse pomaranče pa je manjši od O(V*S), zato ga ne upoštevamo.

V odgovor na Matija Lokar

Risović: Pot najvišje cene v grafu

od Benisa Risović -

Problem: V tehtanem neusmerjenem grafu poiščemo pot najvišje cene od danega vira do katerega koli drugega vozlišča v grafu, ki je večje od dane cene. Pot ne sme vsebovati ciklov.

V odgovor na Benisa Risović

Ali bi lahko s podobnim algoritmom iskali tudi najcenejšo pot?

od Benisa Risović -

Algoritem bi lahko nekoliko modificirali in poiskali pot z najnižjo ceno v grafu. V posebnem primeru, ko so vse cene v grafu pozitivne, bi bilo potrebno pogledati le poti prve stopnje iz podanega začetnega vozlišča in med istimi izbrati povezavo z najnižjo ceno. Preverjanje vseh poti iz začetnega vozlišča do katerega koli drugega vozlišča ni potrebno, saj se bo ob pregledu poti druge stopnje cena povečala.

Medtem ko imamo v grafu tudi negativne uteži se lahko zgodi, da nam bo določena povezava z utežjo -10 prispevala k bolj optimalni rešitvi in v tem primeru preverimo vse možne poti. 

Za iskanje najcenejše poti v grafu se uporabljajo nekoliko drugačni pristopi, v odvisnosti od specifikacij problema. Znana tovrstna problema sta ''Problem trgovskega potnika'' in ''Problem razvoza''.  Več o problemu trgovskega potnika si lahko ogledate na povezavi https://en.wikipedia.org/wiki/Travelling_salesman_problem. Za problem razvoza prilagam članek, ki sem ga lani pripravila pri predmetu Komuniciranje v matematiki.


V odgovor na Benisa Risović

Ali bi lahko pregledana vozlišča hranili v drugi obliki?

od Benisa Risović -

Pri osnovnem algoritmu iskanja v širino je dovolj da si zapomnimo podatek o pregledanih vozliščih, lahko jih hranimo v seznamu, pomembno je, da običajno ne obiskuje že odkritih vozlišč. To ne ustreza našim pogojem, če želimo zajeti vse možne poti iz danega vozliča, zato to preverjanje odstranimo iz osnovnega algoritma. V seznamu pregledanih vozlišč, poleg vozlišča in skupne cene do tega vozlišča, hranimo še pot. Ta pot predstavlja pot po kateri smo prišli od začetka do tega vozlišča. Potem vemo, da bi dobili cikel, če je naslednje vozlišče že na tej trenutni poti, zato tega vozlišča ne dodamo.

Namesto seznama, za shranjevanje podatkov, lahko uporabimo tudi vrsto :

     > vrsta = deque()

     > vrsta.append((trenutni_vrh, trenutna_cena_poti, nabor_do_sedaj_obiskanih_vozlišč))

V vrsti seveda spet hranimo potrebne podatke.

V odgovor na Benisa Risović

Ali obstaja še kakšen način, na kateri lahko hranimo podatke?

od Benisa Risović -

Sama implementacija grafa je poljubna. Podatke lahko hranimo s seznamom sosednosti, kjer za vsako vozlišče xi imamo seznam sosedov, če je graf neusmerjen in z matriko sosednosti, imamo n x n matriko, kjer vsaka vrstica in vsak stolpec predstavljata vozlišče. Vrednost elementa ci,j je 1 če in samo če obstaja povezava (xi, xj).
 


V odgovor na Benisa Risović

Ali so uteži lahko tudi negativne? če so lahko, bo rešitev še zmeraj pot od korena drevesa do posameznega lista?

od Benisa Risović -

Uteži so lahko negativne. Ko iščemo pot z najvišjo ceno se v globalnem ne splača sprehajat po poteh z negativnimi utežmi, saj nam znižajo ceno poti. Vendar na lokalni ravni, se nam lahko zgodi, da nas bo negativna povezava, na primer nekje na začetku poti, privedla k najboljši končni rešitvi in bomo s tem ko bomo preverili vse možne poti, le to izbrali za najbolj optimalno. Če povzamem, pot z negativno utežjo je lahko na določenem koraku slaba odločitev, a jo vseeno ''prehodimo'' in dodamo trenutni poti, saj bo mogoče na koncu le ta pot imela najvišjo ceno v primerjavi z ostalimi.  V primeru, ko je negativna utež čisto na koncu naše trenutne najbolj optimalne poti je smiselno, da jo izpustimo in se ustavimo na prejšnjem vozlišču.


V odgovor na Benisa Risović

Kakšna je časovna zahtevnost?

od Benisa Risović -

Časovna zahtevnost algoritma je O(V+E), kjer je V število vozlišč in E število povezav v grafu. Glede na to, da je uporabljan algoritem iskanja v širino, ''Breadth-First Search (BFS)'', O(E)  je lahko med O(1)  in O(V^2).

V odgovor na Benisa Risović

Hitrost algoritma za iskanje najkrajše poti?

od Benisa Risović -

V bistvu moj algoritem ni smiseln za iskanje najkrajše poti, saj bi v tem primeru rešitev bila enostavna in to, vse poti prve stopnje, torej od začetnega vozlišča do njegovih prvih sosedov.  Če bi imeli problem zastavljen nekoliko drugače, na primer, da bi iskali pot od podanega začetnega vozlišča do podanega končnega vozlišča bi uporabili drugačne pristope in poiskali najkrajšo možno pot.

Če pa je mišljeno na najcenejšo pot, glej odgovor na vprašanje: ''Ali bi lahko s podobnim algoritmom iskali tudi najcenejšo pot?''


V odgovor na Benisa Risović

Ali je to edina možnost, da gremo skozi vse poti?

od Benisa Risović -

Pri tem problemu je koncept modificiranega algoritma iskanja v širino edina možnost, ki jo poznam. V posebnih primerih in ob posebnih pogojih bi se dalo algoritem izboljšat.  



V odgovor na Benisa Risović

Ali bi bil algoritem kaj drugačen če bi bil graf usmerjen?

od Benisa Risović -

Običajno v usmerjenem grafu imamo spremenjen seznam sosednosti, kjer za vsako vozlišče Xi, imamo seznam naslednikov in seznam predhodnikov. V neusmerjenem grafu smo imeli en sam seznam sosedov.  V našem primeru to pomeni, da bi iz začetnega vozlišča  preverjali poti samo v smeri, ki jo graf omogoča, oziroma preverimo možne poti do vozlišč iz seznama naslednikov trenutnega vozlišča.


V odgovor na Benisa Risović

Ali bi algoritem učinkovito deloval tudi za zelo veliko število vozlišč?

od Benisa Risović -

Algoritem bi deloval tudi na grafih z veliko vozlišč, je pa časovna zahtevnost algoritma odvisna od števila vozlišč in je O(V+E), kjer je V število vozlišč in E število povezav v grafu in je O(E)  lahko med O(1)  in O(V^2).

V odgovor na Benisa Risović

Časovna zahtevnost

od hana kranjec kelbel -

Pri reševanju z uporabo sklada je časovna zahtevnost 0(n). Če se odločimo za uporabo seznamov pa O(n**2). Menim, da je iz vidika časovne zahtevnosti boljša rešitev z uporabo sklada.

Sigurno bi lahko izboljšala rešitev, vsaj pri zadnjem delu, kjer iščem največjo absolutno razliko med najbližjimi levimi in desinmi elementi.


V odgovor na hana kranjec kelbel

Zakaj pregledujemo seznam iz zadnjega proti prvem elementu

od hana kranjec kelbel -

Seznam pregledujemo iz zadnjega proti prvem elementu, saj s tem omogočimo iskanje desnega najbližjega manjšega elementa.

Ko pogledamo zadnji element v seznamu je sklad prazen. Zato dodamo v seznam rešitev 0, saj zadnji element nima manjšega elementa.

Ko se pa premaknjemo za en element naprej po seznamu pridemo do predzadnjega elementa. Zadnjega pa smo dodali v sklad. Torej, ko pogledamo vrhnji element v skladu pogledamo njegov desni element iz seznama.

Če povzamem s tem si zagotovimo, da so v skladu vedno desni elementi iz seznama.


V odgovor na hana kranjec kelbel

Kaj delamo oziroma skušamo ugotoviti pri tem problemo

od hana kranjec kelbel -

Imamo seznam celih pozitivnih števil. Za vsak element iz seznama poiščemo desni in levi najbližji manjši element. Izračunamo njuno absolutno razliko. Zanima pa nas največja absolutna razlika.


V odgovor na hana kranjec kelbel

ali deluje samo za pozitivna števila

od hana kranjec kelbel -
Moj problem je vključeval reševanje s celimi števili.
V primeru, da bi uporabnik lahko vnesel seznam s pozitivnimi ali negativnimi števili pa bi najverjetneje vključila še kakšen if stavek za določanje načina iskanja najbližjega manjšega elementa.
V odgovor na hana kranjec kelbel

Re: Kaj delamo oziroma skušamo ugotoviti pri tem problemo

od Matija Lokar -

Ali ni tako, da za vsak element x poiščemo prvi element, ki je manjši od x (v levo torej po vrsti gledamo prejšnjega, predprejšnjega, .... v desno pa naslednjega, naslednjega naslednjega ...) Tudi tu bi bilo bolj jasno, če bi razlago opremila s primerom. 

V odgovor na hana kranjec kelbel

Re: Zakaj pregledujemo seznam iz zadnjega proti prvem elementu

od Matija Lokar -

Razlage ne razumem najbolje. Verjetno bi bilo dobro prikazati zraven kak primer ... 

Kaj pa menite ostali?

V odgovor na Matija Lokar

Lapajne: •Kakšna bi bila prostorska zahtevnost?

od Andreja Lapajne -

V primeru rekurzivnega reševanja bi bila prostorska zahtevnost O(n), ker potrebujemo prostor z n elementov niza. V primeru reševanja s pomočjo skladov pa O(1).


V odgovor na Andreja Lapajne

• Kaj se zgodi, če je niz oklepajev prazen?

od Andreja Lapajne -

Če je niz oklepajev prazen se ne zgodi ničesar. Funkcija nima elementov oklepajev, na katerih bi lahko preverjala ali je niz uravnotežen ali ne.


V odgovor na Andreja Lapajne

• A predpostavljamo, da so v vhodnem nizu samo odprti in zaprti oklepaji ali so lahko tudi drugi znaki?

od Andreja Lapajne -

V vhodnem nizu so lahko samo odprti in zaprti oklepaji ene vrste. Moja funkcija dela le za zavite oklepaje, če pa bi želeli izvedeti število zamenjav v izrazu iz navadnih ali oglatih oklepajih, bi bilo v kodi funkcije potrebno ustrezno spremeniti pogoje.


V odgovor na Andreja Lapajne

• Ali bi lahko posplošili algoritem na več različnih oklepajev?

od Andreja Lapajne -

Ne.

Idejo, ki sem imela je bla ta, da bi za vsako vrsto oklepajev definirala svoj par skladov v katere bi hranila oklepaje in z njimi počela to kar sem počela v moji nalogi. Problem pa bi se pojavili, pri gnezdenju oklepajev. Če bi imeli niz oblike '([{]})' bi v našem primeru ta že bil uravnotežen, kar pa v resnici ne velja. Potrebne bi bile še menjave vrstnega reda oklepajev, ne le menjava zaprtega oklepaja v odprt in obratno.


V odgovor na Andreja Lapajne

Časovna zahtevnost

od Andreja Lapajne -

Časovna zahtevnost v primeru reševanja z rekurzijo bi bila O(2^n) Časovna zahtevnost v primeru reševanja s podatkovno bazo skladi pa bi bila O(n), kjer je n število elementov v nizu, kar je časovno ustreznejše.


V odgovor na Andreja Lapajne

Zakaj je pri rekurziji časovna zahtevnost O(2^n)Zakaj je pri rekurziji časovna zahtevnost O(2^n)

od Andreja Lapajne -

Rekurzija ima eksponentno časovno zahtevnost O(2**n), kjer na vsakem koraku dvakrat kliče samo sebe. To bi delala tudi v našem primeru.


V odgovor na Andreja Lapajne

Kako bi nalogo naredila če nebi imela formule, ki ti poda število potrebnih operacij?

od Andreja Lapajne -

Tu odgovarjam še na vprašanji od kje pride formula ter, razlog zakaj je formula taka kot je.


Formulo, ki smo uporabili v rešitvi je oblike:

((len(sklad.podatki) + 1 ) + (len(pomozni.podatki) + 1 )) // 2

Številu elementov sklada smo prišteli ena, enako storili z številom elementov v pomoznem_skladu ter celoštevilsko delili z dva.

Torej, imamo niz sode dolžine, ki ga je potrebno uravnotežiti. Uravnotežen del niza bo sode dolžine (vsak odprt oklepaj ima svoj zaprt oklepaj) in prav tako bo neuravnotežen del sode dolžine. Imeli bomo m število zaprtih oklepajev in n število odprtih oklepajev. Tu imamo dva primera:

  • število obeh oklepajev je sodo

V tem primeru bo število zamenjav točno m/2 + n/2. Na primer: če imamo dva zaprta oklepaja '}}' potrebujemo natanko eno zamenjavo oklepaja, da bomo imeli uravnotežen izraz, enako velja, če imamo dva odprta oklepaja '{{' prav tako potrebujemo n/2 torej 2/2 eno zamenjavo. Število zamenjav nato le seštejmo.

  • število obeh oklepajev je liho

V tem primeru bo število zamenjav navzgor zaokroženo število m/2 + navzgor zaokroženo število n/2 , ki jih na koncu seštejmo. Če imamo na primer tri zaprte oklepaje '}}}' in en odprt oklepaj '{' bo število zamenjav enako vsoti navzgor zaokoroženemu številu 3/2 + navzgor zaokroženemu številu 1/2, kar je 2 + 1 = 3.

Če rešitvi združimo in v pythonu uporabimo funcijo math.ceil, bi rešitev imela obliko:

math.ceil(m/2) + math.ceil(n/2)

V mojem primeru sem se v izogib funkcije math.ceil uporabila celoštevilsko deljenje, kjer sem v obeh primerih števila oklepajev dodala 1, ter dobila zgornjo formulo, ki je tudi uporabljena v implementaciji kode v pythonu.


V odgovor na Matija Lokar

Kako je definiran rob drevesa? zakaj recimo v primeru ni bila 9 v robu?

od Žiga Avbreht -

V robu drevesa ni vozlišča 9, saj ni ne list in ni vsebovan v levem ali desnem robu.

V odgovor na Žiga Avbreht

Re: Kako je definiran rob drevesa? zakaj recimo v primeru ni bila 9 v robu?

od Matija Lokar -
Verjetno bi bilo smisleno tu objaviti še sliko, da točno vidimo primer. Prav tako bi bilo potrebno še enkrat definirati rob (to je bilo pač vprašanje!)
V odgovor na Matija Lokar

Re: Kako je definiran rob drevesa? zakaj recimo v primeru ni bila 9 v robu?

od Žiga Avbreht -

Da lahko definiramo rob drevesa bi najprej se spet spomnili definicije najbolj levega/desnega lista. Najbolj levi list je tisti list do katerega pridemo tako da gremo najprej levo v poddrevo, če obstaja. Če ne obstaja, gremo v desnopoddrevo dokler ne pridemo do lista. Najbolj desni je definirian simetrično.

S pomočjo tega pa nato definiramo rob in sicer, levi/desni rob drevesa: je pot med korenom in najbolj levim/desnim listom. Če koren nima levega/desnega poddrevesa, je že sam levi/desni rob.

Pa se slika iz primera z danim obhodom:

Slika poti po robu drevesa

V odgovor na Matija Lokar

Ali obstajajo kakšni robni primeri, ki bi pomenili, da tvoj algoritem nebi deloval?

od Žiga Avbreht -

Robni primeri, ki jih lako omenim so to da nimamo desnega ali levega poddrevesa in posledično nimamo desnega ali levega roba, vendar to ni problem, saj potem vzamemo koren kot rob tistega poddrevesa ki ga ni.

V odgovor na Matija Lokar

ali bi rešitev lahko preoblikoval tako, da bi funkcija vrnila tabelo obiskanih vozlišč?

od Žiga Avbreht -

Vse kar bi rabili spremeniti v funkciji je da bi definirali tabelo in namesto da izpisujemo, shranjujemo vozlišča v tabelo in na koncu vrnemo tabelo.

V odgovor na Matija Lokar

kako bi se algoritem iskanja teh mejnih vrednosti spremenil, če ne bi smeli začeti iskanja v korenu? bi sploh lahko prišli nazaj do korena?

od Žiga Avbreht -

Če bi algoritem začeli v najbolj levem listu ali najbolj desnem listu bi samo v drugačnem vrstnem redu klicali definirane funkcije in to nam bi vrnilo algoritem, ki začne v želenem robnem vozlišču. Podobno bi lahko spremenili algoritem, če bi začeli v enem izmed robov. Vse kar bi rabili spremeniti je sestavo robne funkcije, recimo spremenili bi levi rob tako, da bi izpisovali od želene točke naprej in nato liste, desni rob in nakoncu od koreno do dane točke. Če pa bi želeli začeti v poljubnem listu pa nevem kako bi modificiral algoritem.

V odgovor na Matija Lokar

Implementacija dveh skladov v tabelo - Časovna zahtevnost

od Don Mohar -

Časovna zahtevnost metod vstavi in odstrani je O(1). Metodi odstrani iz točno določenega mesta(poznata ta indeks v tabeli in ga ne rabita računat) odstranita element - dejansko samo prestavita kazalca vrhov skladov in element pustita v tabeli, dokler se le ta ne prepiše z novim elementom. Metodi vstavi na točno določeno mesto vstavita element v tabelo, prav tako to mesto poznata zaradi kazalcev, ki kažejo na trenutne vrhove skladov.

V odgovor na Don Mohar

Ali lahko še enkrat pojasniš kaj točno je bil problem.

od Don Mohar -
Moja naloga je bila implementirati dva sklada v isto tabelo. Na obeh skladih morata delovati metodi vstavi in odstrani, kjer metodi vstavi v sklada vstavita element ter metodi odstrani vrneta vrhnji element sklada in element tudi odstranita. Naloga od mene zahteva še, da so časovne zahtevnosti teh metod O(1) ter da je hranjenje podatkov prostorsko učinkovito.
V odgovor na Don Mohar

Kakšna je časovna zahtevnost konstruktorja dvaSklada?

od Don Mohar -

Konstruktor razreda dvaSklada izgleda takole:

def __init__(self, n = 10):
        '''sprejme število n, s tem številom uporabnik pove kolikšna je maksimalna skupna velikost obeh skladov
            oz. če uporabnik ne specificira velikosti tabele ima le ta 10 prostih mest'''
        # če je uporabnik zloben in reče, da bo velikost tabele enaka 0 ali manj
        # velikost nastavim na 10
        if n <= 0:
            n = 10
        self.tabela = [None] * n # tabela v kateri bomo hranili sklada
        self.vrh1 = -1
        self.vrh2 = n

Po mojih informacijah(katerih vir je https://stackoverflow.com/questions/50198421/complexity-of-initializing-a-list) je časovna zahtevnost konstrukcije tabele dolžine n, O(n), torej ima konstruktor linearno časovno zahtevnost.

V odgovor na Don Mohar

Bi v tabelo lahko implementirali več kot 2 sklada?

od Don Mohar -

Lahko, en način bi bil da bi tako kot sedaj 2 sklada hranili v skrajnih koncih tabele, ostale sklade pa med njima. Sklada v skrajnih koncih tabele bi imela vsak le po en kazalec vrhov, skladi med njima pa po 2 kazalca, eden bi kazal na dno sklada ter drugi na vrh. Sklade v sredini bi bilo potrebno premikati levo in desno, saj če bi prišlo do česa takšnega:
[elementi prvega sklada, elementi drugega, elti tretjega, par praznih mest, elti zadnjega]
in bi sedaj želeli vstaviti element v prvi sklad bi morali vse elemente drugega in tretjega sklada premakniti v desno. Pogoji za pregledovanje prostora pa bi bilo malenkost drugačni kot so samo za hranjenje dveh skladov.

V odgovor na Don Mohar

Re: Bi v tabelo lahko implementirali več kot 2 sklada?

od Don Mohar -
Vendar časovne zahtevnosti metod posledično ne bi bile več O(1), saj bi sklade premikali s pomočjo iteracije.
Kar želim povedati je, da zahtev začetne naloge ne bi več izpolnjevali, vendar je hranjenje več skladov mogoče.
V odgovor na Don Mohar

Ali algoritem deluje tudi za ogromno število podatkov?

od Don Mohar -

Seveda. Kar se zgodi v konstruktorju je inicializacija tabele dolžine n, katere vsi elementi so na začetku None. Ko vstavimo ogromno podatkov v kateregakoli od skladov ne bo nobenega problema, dokler tabela ne bo polna. Metodi odstrani pa se prav tako ne obremenjujeta s številom podatkov v skladih, dokler ne poskusimo odstraniti elementa iz praznega sklada, tako da bi moral algoritem deluje tudi za ogromno število podatkov.

V odgovor na Don Mohar

Kako bi se obnašal algoritem, če bi imeli rezervirano tabelo dolžine 5, kjer bi bil en sklad prazen, drugi pa bi vseboval le en element?

od Don Mohar -

Tabela bi imela ta en element na prvem ali zadnjem mestu, torej bi izgledala tako
[elt, None, None, None, None] ali pa tako
[None, None, None, None, elt].
V prvem primeru, bi bil atribut vrh1 = 0, torej kazal bi na vrh prvega sklada, ki je na indeksu 0. Drugi kazalec vrh2 pa bi imel vrednost, ki mu jo dodelimo na začetku - vrh2 = n, torej v tem primeru vrh2 = 5.
V drugem primeru, kjer pa bi ta en element bil v drugem skladu, bi kazalca imela sledeče vrednosti: vrh1 = -1 in vrh2 = 4.

V odgovor na Don Mohar

Obstaja kakšen praktičen primer uporabe?

od Don Mohar -

Torej če v naprej vemo, da smo prostorsko omejeni in bomo potrebovali 2 sklada, katerih posamezna velikost ni v naprej predpisana... se stvari dela tako XD

Profesor je na vajah obrazložil prav to vprašanje, jaz pa sem si njegov odgovor slabo zapomnil.
Zato odgovor na to vprašanje sledi v ponedeljek, po konzultaciji z njim :) 

V odgovor na Matija Lokar

Spasić: Povprečja nivojev v dvojiškem drevesu

od Martina Spasić -

Problem: V nepraznem dvojiškem drevesu želimo izračunati povprečno vrednost vozlišč na vsakem nivoju

V odgovor na Martina Spasić

Ali algoritem deluje za prazno drevo?

od Martina Spasić -

Ja, algoritem nemoteno deluje tudi, če mu damo prazno drevo. V tem primeru vrne prazno tabelo povprečnih vrednosti.


V odgovor na Martina Spasić

Kateri od pristopov je boljši?

od Martina Spasić -

Pristopa sta načeloma enakovredna, imata tudi isto časovno zahtevnost. Pri zelo velikih drevesih oziroma pri drevesih z veliko višino je pa boljši pristop BFS (iskanje v širino), saj z njim lažje pregledamo celotno drevo, saj ga pregledujemo po nivojih. Pri DFS (iskanje v globino) se pa lahko pri velikih drevesih zakomplicira, saj moramo priti čisto do konca levega poddrevesa in šele potem pregledati desno poddrevo.


V odgovor na Martina Spasić

Ko obravnavamo časovno zahtevnost, kaj je karakteristična operacija?

od Martina Spasić -

Pri tej nalogi je ključnega pomena, da vsako vozlišče obiščemo natanko enkrat, se pravi je karakteristična operacija obisk vozlišča, saj potem lahko seštejemo vse vrednosti vozlišč na vsakem nivoju.


V odgovor na Martina Spasić

A bi algoritem deloval tudi, če bi imeli na vozliščih negativna števila?

od Martina Spasić -

Ja, algoritem se izvede tudi za negativna števila in lahko vrne tudi negativno povprečje nivoja.


V odgovor na Martina Spasić

Kako vemo, na katerem nivoju smo?

od Martina Spasić -

V bistvu pri BFS ne vemo na katerem nivoju smo (npr. ali smo na četrtem ali petem nivoju). Funkcija nikjer ne izpisuje število trenutnega nivoja, le sešteva vse vrednosti vozlišč in prešteje, koliko jih je. Ko vozlišča iz pomožne vrste vstavimo v vrsto vemo, da smo s pregledovanjem trenutnega nivoja končali, vendar ne vemo kateri nivo je to. Lahko pa v kodi dodamo novo spremenljivko za trenutni nivo, ki jo po tem, ko vsak nivo pregledamo, povečamo.

Pri BFS pa moramo vedeti kje smo, zato bi v sklad dodajali dva podatka, vrednost vozlišča in nivo, na katerem se to vozlišče nahaja, saj dokler ne pregledamo celotnega levega poddrevesa se ne premaknemo na desno poddrevo.


V odgovor na Martina Spasić

Bi se dalo rešitev dobiti tudi s pomočjo sklada?

od Martina Spasić -

Ja, dalo bi se. Pri tem bi sosede dodajali v sklad, najprej pregledamo koren, nato levo poddrevo in na koncu desno poddrevo. Kot sem že odgovorila pri prejšnjem vprašanju, v sklad dodajamo dva podatka, vrednost vozlišča in nivo, na katerem se to vozlišče nahaja.


V odgovor na Martina Spasić

Zakaj elemente hranimo v vrsti, ali navadna tabela ne bi zadostovala?

od Martina Spasić -

Lahko bi šlo tudi s tabelo. Pri vrsti je pomemben vrstni red, zanašamo se na FIFO (first in first out), pri tabeli bi se tako morali sklicevati na indekse. V tem primeru bi se naša tabela morala obnašati kot vrsta.


V odgovor na Martina Spasić

Ali bi pristop deloval tudi, če ne bi imeli dvojiško drevo, pač pa bi bilo drevo z možnostjo večih sinov?

od Martina Spasić -

Pristop deluje tudi za drevo, ki ni dvojiško, saj sta tako BFS kot DFS definirana za poljuben graf. Namesto kvečjemu 2 sinova bi imeli več sinov, in bi se posledično sklicevali ne le na levo in desno poddrevo, ampak na več poddreves.


V odgovor na Matija Lokar

Iskanje para števil v dvojiškem iskalnem drevesu, ki se seštejeta v dano vsoto

od Ajla Sović -

Dano je dvojiško iskalno drevo in vsota. Želimo poiskati tak par števil v drevesu, ki se sešteje v dano vsoto.

V odgovor na Ajla Sović

prvi algoritem, ki si ga predstavila verjetno deluje v vseh drevesih? ni nujno da so urejena?

od Ajla Sović -

Ja, prvi predstavljeni algoritem deluje v vseh drevesih ne glede na to ali je dvojiško iskalno drevo ali ne.


V odgovor na Ajla Sović

Re: prvi algoritem, ki si ga predstavila verjetno deluje v vseh drevesih? ni nujno da so urejena?

od Matija Lokar -
Pazimo! Urejeno drevo je drevo, kjer je vrstni red poddreves (oz. sinov) pomemben. Urejenost je torej urejenost oblike in ni pomembno, kakšni so podatki, ki jih hranimo v vozliščih. Vsako dvojiško drevo je urejeno drevo, ker govorimo o levem in desnem sinu. Iskalno dvojiško drevo je seveda urejeno (ker je dvojiško), s tem da ima še dodatno "urejenost" glede podatkov v vozliščih.

Torej bo potrebno odgovor bolj natančno oblikovati!
V odgovor na Ajla Sović

kaj če je parov več? Kako poiskati vse pare v zadnjem algoritmu?

od Ajla Sović -

Žal, moj algoritem vrne samo en par števil. Obstaja sicer način, ki je podoben algoritmu s tabelo, le da pri tem uporabimo sklad. Na začetku bi imeli dva prazna sklada in bi potem uporabili „prednost“ da delamo s dvojiškim iskalnim drevom.  V prvi sklad bi dali najbolj leva vozlišča skupaj s korenom, ki bo prvi element prvega sklada;  v drugi sklad pa najbolj desna vozlišča skupaj s korenom, ki v tem primeru bo zadnji element našega sklada. Na enak način kot pri predstavljenemu algoritmu bi primerjali vsote. Imamo spet dve puščici ki kažeta na vrh prvega in drugega sklada.




Na podoben način pregledujemo vsote parov števil na kateri kažeta puščici, ter ustrezno „potiskamo“ navzdol. Več o tem si lahko preberete tudi na spletni strani: https://www.geeksforgeeks.org/find-all-the-pairs-with-given-sum-in-a-bst-set-2/

V odgovor na Ajla Sović

algoritma 2 in 3 imata enako časovno zahtevnost, ampak kateri je hitrejši?

od Ajla Sović -

Na podlagi meritev ki sem jih opravila, iskaže se da je drugi algoritem malce hitrejši.



V odgovor na Ajla Sović

katerega od načinov se najbolj splača izbrati?

od Ajla Sović -

 Iskaže se, da je algoritem s pomočjo množice najhitrejši, kar pomeni da se ga najbolj splača izbrati.

V odgovor na Ajla Sović

kakšna je časovna zahtevnost algoritma z tabelo?

od Ajla Sović -

Časovna zahtevnost algoritma s tabelo je O(n), kjer n predstavlja število elementov v tabeli.

V odgovor na Ajla Sović

ali je tretji pristop najbolj primeren glede na časovno in prostorsko zahtevnostjo?

od Ajla Sović -

Najbolj primeren pristop je pregled elementov s pomočjo množice.

V odgovor na Ajla Sović

kdaj se zanka ustavi pri zadnjem algoritmu, če taka vsota ne obstaja?

od Ajla Sović -

spomnimo se zadnjega algoritma: v urejenem seznamu seštevamo elemente na način, da seštejemo en element iz leve strani z elementom z desne strani in nato ustrezno se premikamo k večjemu/manjšemu elementu v tabeli.

Pri zadnjem algoritmu se zanka ustavi ko je levo == desno; oziroma ko se „puščici sprimeta“.


V odgovor na Ajla Sović

ali lahko kdaj uporabimo \ “prednost\ “ da delamo z iskalnim dvojišlim drevesom?

od Ajla Sović -

Dejstvo da delamo z dvojiškim iskalnim drevesom nam lahko pomaga pri brute force algoritmu, kjer si izberemo eno vozlišče in primerjamo z ostalimi vozlišči. Ker vemo da so v dvojiškem iskalnem drevesu levo od korena števila, ki so manjša;  desno pa števila, ki so večja od korena, lahko si na podlagi razlike med dano vsoto in izbranega vozlišča olajšamo delo in pregledujemo samo eno stran drevesa.

V odgovor na Ajla Sović

ali bi se kaj pri algoritmu spremenilo če naše drevo nebi bilo iskalno?

od Ajla Sović -

Recimo, pri drugem algoritmu elemente vstavljamo v množico, kjer ponovljenih elementov ni. Pri tretjem algoritmu pa drevo itak preoblikujemo v urejeni seznam.

V odgovor na Matija Lokar

Berdnik: Kako ugotoviti, ali neusmerjen graf vsebuje cikel?

od Ana Berdnik -


Odgovori na vprašanja predstavitve Kako ugotoviti, ali neusmerjen graf vsebuje cikel?

V odgovor na Ana Berdnik

Ali bi algoritma delovala tudi če bi imelo drevo več kot en cikel in ali bi lahko funkcija tudi vračala dejanski cikel?

od Ana Berdnik -

Algoritma, ki sem ju opisala, vrneta le odgovor (True ali False) ali neusmerjen graf (povezan ali nepovezan) vsebuje cikel ali ne. Odgovor vrneta po prvem najdenem ciklu. Bi se pa seveda oba algoritma dalo preoblikovati tudi tako, da bi vračala število ciklov ali pa vozlišča v ciklu ipd. Seveda pa vsaka taka implementacija zahteva še nekaj dodatnega dela.


V odgovor na Ana Berdnik

Re: Ali bi algoritma delovala tudi če bi imelo drevo več kot en cikel in ali bi lahko funkcija tudi vračala dejanski cikel?

od Matija Lokar -
In kakšna bi bila ključna sprememba - tako glede tega, da bi algoritem vrnil cikel (to mislim, da bi šlo) kot tega, koliko je ciklov (postavlja se mi vprašanje, če res možno algoritem spremeniti tako, da bi prešteli vse cikle - npr. v polnem grafu na n točkah jih je vsaj n!, saj je toliko že Hamiltonovih (no, če ne je cikel 1 - 2 - 3 - 1 enak ciklu 2 - 3 - 1- 2 , jih je manj, ampak še vedno eksponentno), če pa štejemo še krajše cikle ... Glej recimo https://math.stackexchange.com/questions/1363963/number-of-cycles-in-complete-graph
V odgovor na Matija Lokar

Re: Ali bi algoritma delovala tudi če bi imelo drevo več kot en cikel in ali bi lahko funkcija tudi vračala dejanski cikel?

od Ana Berdnik -
Če nas zanima le število vseh ciklov, se lahko implementaciji, ki sem jo zapisala, preprosto doda ena spremenljivka, ki šteje število ciklov v grafu. Algoritem tako, ko najde cikel, ne vrne True, pač pa to prišteje k omenjeni spremenljivki. To varianto sem preizkusila in deluje, vendar le za disjunktne cikle.
Dodatno sem našla varianto, ki vrača izpise vseh teh ciklov na https://www.google.com/amp/s/www.geeksforgeeks.org/print-all-the-cycles-in-an-undirected-graph/amp/, ki pa prav tako žal deluje le na disjunktnih ciklih.

S pomočjo teorije grafov bi se glede na dodano povezavo v prejšnjem odgovoru dalo izračunati število grafov v polnem grafu, nisem pa sigurna ali bi lahko vse znano razširili tudi na iskanje vseh ciklov v poljubnem grafu.
V odgovor na Ana Berdnik

Kateri od predstavljenih algoritmov za iskanje ciklov se uporablja pogosteje?

od Ana Berdnik -

Oba algoritma imata enako časovno zahtevnost, vendar pa je prostorska zahtevnost različna. Pri BFS si mora algoritem hraniti podatke vseh vozlišč v posameznem nivoju, medtem ko se lahko DFS zapiše tako, da hrani podatke le svojega predhodnika. Iz tega razloga se drug algoritem uporablja nekoliko pogosteje, še posebej pri večjih grafih.


V odgovor na Ana Berdnik

Kakšna je časovna zahtevnost algoritmov?

od Ana Berdnik -

Implementacija razreda Graf in algoritmov, ki sem jih zapisala je bazirana na povezavah med vozliščih. Torej je velikost problema število povezav. V najboljšem primeru, lahko cikel zaznamo že takoj na začetku in je tako časovna zahtevnost konstantna. V najslabšem primeru, ko pa graf ne vsebuje cikla, pa se moramo pri obeh algoritmih sprehoditi po vseh teh povezavah. Zato je v tem primeru časovna zahtevnost O(E), kjer je E število povezav.


V odgovor na Ana Berdnik

Kje se v praksi uporabljata ta dva algoritma?

od Ana Berdnik -

Poleg iskanja cikla, se algoritma lahko uporabljata tudi na mnogih drugih problemih.

BFS je predvsem učinkovit za iskanje najkrajše poti med dvema poljubnima vozliščema v grafu, ugotavljanje ali je graf dvodelen pa tudi za pomoč pri reševanju Rubikove kocke in iskanju sosednjih lokacij pri navigaciji.

DFS pa se uporablja pri topološkem urejanju, ugotavljanju ali je graf 2-povezan, ugotavljanju ali je graf ravninski ter reševanju ugank z eno samo rešitvijo, kot sta labirint in sudoku.


V odgovor na Ana Berdnik

Glede na to, da si rekla da začnemo v poljubnem vozlišču, a bi v tem primeru obiskali koren ali samo poddrevo tega vozlišča?

od Ana Berdnik -

Vprašanja ne razumem popolnoma. Pri obeh algoritmih obiščemo vsako vozlišče (če seveda prej ne najdemo cikla), iz katerega začnemo pa je popolnoma vseeno, saj tudi če bomo začeli v nekem vozlišču recimo znotraj levega poddevesa, bomo s časom obiskali tudi sam koren drevesa, ali obratno. Oba algoritma sta tako (v primeru, da graf ne vsebuje cikla) le dva načina pregleda grafa.


V odgovor na Matija Lokar

Vertikalni obhod dvojiškega drevesa

od Hana Lukež -

Algoritem, ki izpiše vrednosti vozlišč od zgoraj navzdol in od leve proti desni

V odgovor na Hana Lukež

Kakšna je časovna zahtevnost algoritma?

od Hana Lukež -

Velikost problema je število vozlišč n, število operacij za določeno vozlišče, pa je v najslabšem primeru log(n). Torej je časovna zahtevnost za predstavljen algoritem O(n*log(n)).


V odgovor na Hana Lukež

Re: Kakšna je časovna zahtevnost algoritma?

od Matija Lokar -
Zakaj pa je število operacij za določeno vozlišče v najslabšem primeru log(n)? Kaj pa v najbolšem?
V odgovor na Matija Lokar

Re: Kakšna je časovna zahtevnost algoritma?

od Hana Lukež -
V bistvu v algoritmu samo urejamo seznam števil, kar vemo, da traja O(n*log(n)). Urejamo pa po treh parametrih (x-koordinati, y-koordinati, vrednosti vozlišča), kar bi pomenilo O(3*n*log(n)). Zaradi O notacije, ki pomeni asimptotična zahtevnost, pa lahko izpustimo konstanto 3, saj pri velikih n-jih postane irelevantna. Tako dobimo časovno zahtevnost O(n*log(n)).
V odgovor na Hana Lukež

Kakšna je prostorska zahtevnost algoritma?

od Hana Lukež -

Prostorska zahtevnost za dani algoritem je kar število vozlišč drevesa, torej O(n).

V odgovor na Hana Lukež

Re: Kakšna je prostorska zahtevnost algoritma?

od Matija Lokar -
V odgovor na Matija Lokar

Re: Kakšna je prostorska zahtevnost algoritma?

od Hana Lukež -
Vsa vozlišča shranimo v en seznam oz. 3 parametre: x-koordinato, y-koordinato in vrednost vozlišča. Dobimo torej časovno zahtevnost 3*n, kjer je n število vozlišč drevesa. Ker pa pri velikih n-jih konstanta 3 postane irelevantna, pa dobimo časovno zahtevnost O(n).
V odgovor na Hana Lukež

Kakšne so prednosti vertikalnega obhoda?

od Hana Lukež -

Prednost je ta, da lahko v primeru, ko imamo res veliko dvojiško drevo, si lažje predstavljamo, katera vozlišča se prekrivajo.


V odgovor na Hana Lukež

Ali bi algoritem deloval tudi, če bi drevo vsebovalo negativna števila?

od Hana Lukež -

Algoritem seveda deluje tudi za negativne vrednosti vozlišč. Prilagam kodo in primer drevesa, z nekaterimi negativnimi vrednosti vozlišč, kjer lahko sami preizkusite, da deluje.

 

Primer: drevo =

Drevo(28,levo=Drevo(23,levo=Drevo(222,levo=Drevo(13),desno=Drevo(5)),desno=Drevo(25,levo=Drevo(5),desno=Drevo(66))),desno=Drevo(43,levo=Drevo(2,levo=Drevo(-12),desno=Drevo(-7)),desno=Drevo(93,levo=Drevo(-3),desno=Drevo(103))))


V odgovor na Hana Lukež

Ali bi lahko konstruktorju drevesa dodal še to, da vemo na kateri vertikali je poljubno vozlišče?

od Hana Lukež -

Dejansko nam x-koordinata pove na kateri vertikali je poljubno vozlišče. Torej, če bi nam bila prioriteta, da vemo na kateri navpičnici je posamezno vozlišče, bi potem samo poleg vrednosti vozlišča izpisali zraven še x-koordinato, kot nek par vrednosti.


V odgovor na Hana Lukež

6. Zakaj bi drevo obhodili na tak način namesto po nivojih?

od Hana Lukež -

Če vi drevo obhodili po nivojih, potem ne bi vedeli katera vozlišča se prekrivajo, saj ne vemo na kateri navpičnici so vozlišča, ampak vemo samo na kateri horizontali so. Torej če bi imeli naslednje drevo:



Naslednji:

6

5, 53

22, 33, -1, 7

0

 

Več o obhodu po nivojih pa si lahko preberete na spletni strani: https://www.geeksforgeeks.org/print-level-order-traversal-line-line/


V odgovor na Hana Lukež

Ali ta algoritem samo pregleda drevo?

od Hana Lukež -

Ta algoritem pregleda drevo in izpiše seznam seznamov. V vsakem seznamu so vrednosti vozlišč na isti vertikali, po vrstnem redu od zgoraj navzdol.


V odgovor na Hana Lukež

V katerih primerih bi bil vertikalen pregled uporaben?

od Hana Lukež -

Vertikalen pregled bi bil uporaben, kadar bi želeli vedeti katera vozlišča se prekrivajo v drevesu. Ko imamo podano neko dvojiško drevo si ne moremo tega predstavljati, ampak če pa imamo napisane koordinate vozlišč pa lahko vidimo katera vozlišča imajo iste koordinate.


V odgovor na Hana Lukež

Zakaj uporabljamo ta algoritem in določamo koordinate vozlišča? Zato, da prehodimo drevo, ali?

od Hana Lukež -

Torej kot sem že omenila  v prejšnjih odgovorih: Vertikalen pregled bi bil uporaben, kadar bi želeli vedeti katera vozlišča se prekrivajo v drevesu. Ko imamo podano neko dvojiško drevo si ne moremo tega predstavljati, ampak če pa imamo napisane koordinate vozlišč pa lahko vidimo katera vozlišča imajo iste koordinate.


V odgovor na Matija Lokar

Ali je vrsta skladna permutacija druge vrste

od anže ozimek -

Problem: Preverimo ali je podana vrsta skladna permutacija druge, tudi podane vrste.

V odgovor na anže ozimek

Kakšna je časovna in prostorska zahtevnost algoritma?

od anže ozimek -

Časovna zahtevnost je O(n). Vemo, da bomo enkrat šli čez vse elemente vhodne vrste. Na vsakem koraku se nam lahko zgodi, da kakšen element sklada izbrišemo torej naredimo več kot eno primerjavo. Teh primerjav pa ne more biti poljubno mnogo saj več kot jih je na enem koraku manj jih bo na naslednjem, ker se sklad prazni. Iz tega potem sklepamo, da očitno nimamo več kot linearne časovne zahtevnosti.

Prostorska zahtevnost pa je tudi O(n) saj samo napolnimo sklad z n elementi (najslabši primer).


V odgovor na anže ozimek

Ali se lahko kdaj hitro opazi, da ne gre za permutacijo?

od anže ozimek -

Poglejmo primer:

Vhodna vrsta = [2,3,1,4,5], izhodna vrsta = [5, 3, 2, 1, 4].

Opazimo, da če imamo v izhodni vrsti element (v primeru je ta 5), ki se nahaja na koncu vhodne vrste, obstaja samo ena rešitev in sicer obraten vrstni red vhodne vrste. Za zgornji primer bi torej dobili, da izhodna vrsta ni skladna permutacija vhodne vrste, če pa bi izhodna vrsta bila [5, 4, 1, 3, 2] bi imeli skladno permutacijo. Sedaj je vprašanje ali se nam bi splačalo ta primer obravnavati v programu. Po mojem mnenju se nebi, saj če imamo za izhodno vrsto podano naključno generirano permutacijo je verjetnost, da je v njej prvi element zadnji element vhodne vrste enaka 1/n, kjer je n število elementov. Kot vidimo bi nam implementacija te zaustavitve pomagala pri približno 1/n primerih torej zelo malo če imamo opravka z dolgimi permutacijami.

V odgovor na anže ozimek

Ali obstajajo tudi vrstne permutacije, torej da namesto s skladom permutacijo preverjamo z vrsto?

od anže ozimek -

Ne, saj če pomislimo vidimo, da si z vrsto ne moremo pomagati pri spreminjanju vrstnega reda. Če elemente vstavljamo v vrsto bodo ostali v enakem vrstnem redu.

V odgovor na anže ozimek

Koliko različnih skladnih vrst ima lahko posamezna vrsta?

od anže ozimek -

Mislim, da vprašanje govori o skladnih permutacijah vrste. Same eksplicitne formule za vse možne skladne permutacije n elementov sicer nimamo (kot jo imajo vse možne permutacije n!), vendar lahko povem to, da jih je v primerjavi z vsemi torej n! zelo malo.

Če imamo 3 elemente ima vsaka permutacija med njimi 5 možnih skladnih permutacij. To pomeni, da če vzamemo vrsto s tremi elementi (vrstni red poljuben) in dobimo eno od njenih permutacij, le v enem primeru le-te ne moremo dobiti s permutacijo s skladom.

Primer: iz vhodne vrste [1,3,2] ne moremo dobiti s pomočjo sklada permutacije [2,1,3] (to se zlahka vidi iz odgovora na zgornje vprašanje Ali se lahko kdaj hitro opazi, da ne gre za permutacijo?).

Torej je skladnih permutacij za vrsto s tremi elementi 5 v primerjavi z vsemi ki jih je 3! = 6.

Za vrsto s štirimi elementi je skladnih permutacij 14 od vseh možnih 4! = 24.

Za vrsto s petimi elementi je skladnih permutacij 42 od vseh možnih 5! = 120.

Za vrsto s šestimi elementi je skladnih permutacij 132 od vseh možnih 6! = 720.

Za vrsto s sedmimi elementi je skladnih permutacij 429 od vseh možnih 7! = 5040.

Za vrsto s osmimi elementi je skladnih permutacij 1430 od vseh možnih 8! = 5040.

Za vrsto s devetimi elementi je skladnih permutacij 4862 od vseh možnih 9! = 362880.

Iz zadnje lahko razberemo, da je skladnih permutacij okoli 1% vseh možnih če imamo v vrsti več kot 9 elementov, torej njihovo število res zelo hitro pada.

V odgovor na anže ozimek

Kaj se zgodi če se elementi v vrsti ponavljajo?

od anže ozimek -

Moja rešitev nebi delovala dobro če bi se lahko elementi ponavljali. Vendar če pomislimo vemo, da ko govorimo o permutacijah imamo v mislih množico, kjer se elementi ne ponavljajo. Torej če za permutacije velja, da se morajo elementi razlikovati med seboj sem mnenja, da to velja tudi za permutacije s skladom.


V odgovor na Matija Lokar

Odgovori na vprašanja za sladkarije

od ALJAŽ PENCA -

Odgovori na vprašanja za problem SLADKARIJE

V odgovor na ALJAŽ PENCA

časovna zahtevnost?

od ALJAŽ PENCA -

Predstavil sem dva možna načina, kako lahko problem rešimo. En način(brute force) ima časovno zahtevnost O(n^2), drugi pa ima časovno zahtevnost O(n).


V odgovor na ALJAŽ PENCA

Re: časovna zahtevnost?

od Matija Lokar -
Dobro je, da se trditve argumentira! Da o tem, da ne vemo, kaj je n, oz. kaj je velikost problema sploh ne govorimo ;-)
V odgovor na ALJAŽ PENCA

ali je druga metoda potem sploh primerna, če ni nujno da se ocene otrok na koncu ujemajo s številom sladkarij, ki jih dobijo?

od ALJAŽ PENCA -

Druga metoda je boljša od prve in bo tudi vedno delovala. Zanimivost, ki sem jo povedal je, da otroci, ki imajo isto oceno ne-nujno dobijo isto število sladkarij. Na sliki vidimo dva otroka za oceno 3, vendar en dobi 2 sladkariji, drug pa samo 1.


V odgovor na ALJAŽ PENCA

Re: ali je druga metoda potem sploh primerna, če ni nujno da se ocene otrok na koncu ujemajo s številom sladkarij, ki jih dobijo?

od Matija Lokar -
V odgovor na Matija Lokar

Re: ali je druga metoda potem sploh primerna, če ni nujno da se ocene otrok na koncu ujemajo s številom sladkarij, ki jih dobijo?

od ALJAŽ PENCA -
V odgovor na ALJAŽ PENCA

sladkarije v tem primeru \ ‘\ ‘ne delimo\ ‘\ ‘, a je mogoče kakšna povezava s problemom 0/1 nahrbtnika?

od ALJAŽ PENCA -

Sladkarije moramo vedno razdeliti. Prvi pogoj je, da vsak otrok dobi vsaj eno sladkarijo.


V odgovor na ALJAŽ PENCA

kaj pa, če imamo n otrok in imajo vsi isto oceno? kaj se zgodi če imajo vsi enake ocene ?

od ALJAŽ PENCA -

Potem pa bi vsi dobili samo eno sladkarijo in bi tako potrebovali le n sladkarij. Prvi pogoj bi bil izpolnjen in noben od otrok nima večje ocene od sosedov, torej nihče ne dobi več kot eno sladkarijo.


V odgovor na ALJAŽ PENCA

če si otrok z najboljšo oceno, kam se moraš postaviti, da dobiš največ bonbonov?

od ALJAŽ PENCA -

Najbolje je gledati koliko otrok zapored ima večjo oceno od svojega soseda. Recimo na primeru bi se otroku z oceno 7 bolj splačalo postaviti za eno mesto bolj levo(desno od otroka z oceno 5) in bi dobil 5 sladkarij namesto samo 2.


Priponka otroci.png
V odgovor na ALJAŽ PENCA

bi lahko rešitev izboljšali z uporabo kakšne druge podatkovne strukture?

od ALJAŽ PENCA -

Časovne zahtevnosti ne bi mogli zmanjšati pod O(n), lahko pa izboljšamo prostorsko zahtevnost na O(1), kjer bi uporabili samo eno spremenljivko.


V odgovor na ALJAŽ PENCA

kako pridemo do 2. algoritma (kako vemo, da dobimo, če vzamemo maximum tabel res pravo rešitev)? zakaj ta algoritem dejansko pripelje do rešitve? kakšna je teorija za tem, da vzamemo maksimum obeh tabel in dobimo optimalno rešitev?

od ALJAŽ PENCA -

Izkaže se, da je važno koliko otrok ima “zapored” večjo oceno od svojega soseda(vsi od istega soseda, recimo da imajo trije otroci večjo oceno od svojega levega soseda zapored kot na sliki imajo otrok z oceno 3, oceno 4 in oceno 5). Torej če pogledamo kako ocene naraščajo od leve proti desni, potem pa še od desne proti levi, bo max obeh rešitev za posameznega otroka pravilna.


Priponka otroci.png
V odgovor na ALJAŽ PENCA

ali prav razumem, da je eno izmed pravil deljenja sladkarij to, da otrok z večjo oceno dobi več sladkarij le od sosedov z manjšo oceno, ocena glede na celo vrsto torej ni pomembna?

od ALJAŽ PENCA -

Nekako tako ja. Seveda je sama ocena še vedno pomembna, saj otroci, ki bodo imeli najmanjšo oceno, bodo vedno dobili le eno sladkarijo, zato  se splača imeti višjo oceno .

V odgovor na ALJAŽ PENCA

imamo podane ocene otrok; kako jih zarvrstimo, da bo poraba bonbonov največja/najmanjša?

od ALJAŽ PENCA -

Da bo poraba največja, jih postavimo v naraščajoči/padajoči vrstni red, da bo vsak imel eno sladkarijo več od soseda in bo zato naraščanje sladkarij večje. Moramo pa paziti, da če imamo otroke z itso oceno, jih ne postavimo enega za drugim, saj s tem uničimo to metodo, zato na koncu prve razporeditve naredimo še eno(in še eno, glede na to, koliko otrok ima isto oceno). Glej sliko 1 za primer. Da jih porabimo najmanj, pa tako da ocene čim več “skačejo” gor in dol. Torej bi na prvo mesto dali nekoga z visoko oceno, na drugo mesto nekoga, ki ima manjšo od prvega, potem na tretje nekoga, ki ima večjo od drugega, na četrto spet nekoga, ki ima manjšo od tretjega. glej sliko 2. Vidimo, da v primeri 1 potrebujemo 18 sladkarij, v primeru 2 pa 10


Priponka 1.png
V odgovor na ALJAŽ PENCA

ali je možno, da dobijo vsi enako število sladkarij?

od ALJAŽ PENCA -

Ja, če imajo vsi enako oceno. V tem primeru bi vsi dobili eno sladkarije. Da bi vsi dobili recimo 2 sladkariji pa je nemogoče. Otrok, ki bo imel najmanjšo oceno bo vedno imel le 1 sladkarijo, ne glede na sosede in ne bo nikdar imel dveh ali več sladkarij.