Õppetund
Teooria — Rekursioonipuu uurija
Rekursioonipuu sisaldab iga väljakutse kohta ühte sõlme. Juur on esialgne väljakutse ja sõlme lapsed on tema enda tehtud uued väljakutsed. Puust saab lugeda kolme arvu. Sõlmede koguarv annab tööaja "ühe väljakutse" ühikutes. Puu kõrgus näitab pinu sügavust. Erinevate sõlmede arv aga näitab tööaega olukorras, kus iga vastus jäetakse kohe esimesel leidmisel meelde.
Kuidas nähtut lugeda
Leht avaneb algolekus fib(6) peal. Selle puu on kogu ulatuses joonistamiseks piisavalt väike: 25 sõlme, millest 7 tähistavad vastava alamülesande esimest esinemist. Seetõttu näitabki erinevate alamülesannete lahter arvu 7 ja väljakutseid alamülesandele näitab 3,6. Suurim sügavus on 5, mis kulgeb mööda ahelat fib(6) → fib(5) → … → fib(1). Kõigist 25 väljakutsest 13 jõuavad baasjuhuni, ülejäänud 12 aga liidavad igaüks kaks tagastatud väärtust.
- Ei kehti, kui
- Näitaja väljakutseid alamülesandele annab lubaduse puhverdamise kasulikkuse kohta. Hanoi torni korral see lubadus murdub. Hanoi n = 20 juures annab 2 097 151 väljakutse peale vaid 21 erinevat alamülesannet. See teeb 99 864,3 väljakutset alamülesandele, mis on 95,8 korda suurem näitaja kui Fibonaccil sama n-i korral. Puhverdamine ei säästa siin midagi praktilist. Väljakutse
hanoi(20)vastus on 1 048 575 liigutusest koosnev nimekiri. Varem meelde jäetud nimekirja tagastamine nõuab sama palju ressurssi kui selle uuesti genereerimine. Puhvertabel tasub end ära siis, kui vastus on lühike ja puu on suur. Fibonacci vastus on üksainus täisarv. Hanoi vastuseks on aga terve lahtikirjutatud puu ise.
Ülesanded täielikult lahendatud
-
Kutsete arvu suletud kuju, kui naiivne fib(10) teeb 177 kutset 6 sammu
Tööriist näitab, et naiivne
fib(10)teeb 177 väljakutset jafib(11)teeb 287. Leia väljakutsete arvu kinnine kuju ja tõesta see. Seejärel arvuta, kui kaugele jõuab naiivne Fibonacci ühe sekundiga masinal, mis suudab teha 108 väljakutset sekundis.-
Liida kummalegi arvule üks. Saad 178 ja 288. Mõlemad on paarisarvud ja nende pooled on 89 ning 144, mis vastavad jada liikmetele F11 ja F12. Püstitame hüpoteesi, et C(n) = 2F(n+1) − 1, kusjuures F(1) = F(2) = 1.
-
Puu selgitab, kust selline kahekordistumine pärineb. Iga sisemine sõlm teeb täpselt kaks väljakutset ja iga leht ei tee ühtegi. Seega on L lehega puus L − 1 sisemist sõlme ja kokku 2L − 1 sõlme. Tööriist näitab n = 10 korral 89 baasjuhtu ja 2 × 89 − 1 = 177.
-
Vaatame esmalt baasjuhte.
fib(0)jafib(1)tagastavad väärtuse ilma rekursioonita, seega C(0) = C(1) = 1. Mõlemad avaldised 2F(1) − 1 ja 2F(2) − 1 annavad samuti väärtuseks 1. -
Nüüd teeme induktsioonisammu. Eeldame, et valem kehtib n − 1 ja n − 2 korral. Väljakutse n juures moodustab ühe sõlme koos oma kahe alampuuga. Nende all olevad kaks Fibonacci arvu liituvad jada definitsiooni enda põhjal. Võttes n = 11 saame 2 × 144 − 1 = 287, mida trükib välja ka tööriist.
-
Jätame puu nüüd kõrvale. Binet' valem annab F(m) = (φm − ψm)/√5, kus φ = 1,6180 ja |ψ| < 1. Seega on F(m) φm/√5 ümardatuna lähima täisarvuni ja C(n) ≈ 2φn+1/√5. Üks sekund kiirusel 108 väljakutset sekundis lubab teha 108 väljakutset. See fikseerib φn+1 väärtuseks 1,1180 × 108.
-
Võtame logaritmid. ln(1,1180 × 108) = 18,5323 ja ln φ = 0,4812. Seega n + 1 = 38,51 ning n = 37,5. Ümardame allapoole, sest murdosaga väljakutse ei jõua lõpule.
Vastus
n = 37. Tööriist kinnitab kahte naabrit: 78 176 337 väljakutset n = 37 korral ja 126 491 971 väljakutset n = 38 korral. Sealt edasi kahekordistab iga järgmine 1,44 n-i väärtuses tehtava töö, sest ln 2 / ln φ = 1,44. Samal ajal näitab erinevate alamülesannete lahter n = 37 juures arvu 38. Seitsekümmend kaheksa miljonit väljakutset kolmekümne kaheksale küsimusele vastamiseks ongi kogu dünaamilise planeerimise argument ühte lausesse kokku võetuna.
-
-
Kolm haru, mis kasvavad aeglasemalt kui kaks 6 sammu
Kolme sammuga trepp kutsub end igas sõlmes kolm korda, Hanoi torn kaks. Laadi Trepp, kolm haru, n=20, arvuta välja, kumb kahest puust kiiremini kasvab, ja otsusta, mida hargnemistegur juhisena väärt on.
-
Loe rekurrents definitsioonist, mitte pildilt. Üks väljakutse sõlme enda jaoks, siis veel kolm kohtades n − 1, n − 2 ja n − 3, ja kõik, mis on 2 või vähem, tagastab ilma rekursioonita.
-
Eelda, et arv kasvab geomeetriliselt, C(n) ≈ A xⁿ, ja asenda. Jaga läbi x-iga astmes n − 3 ning ees seisev 1 jääb madalamat järku mürana maha, alles jääb kuupvõrrand. Selle ainus reaalarvuline lahend on 1,8392868, tribonacci konstant.
-
Sama retsept ülejäänud kahel definitsioonil. Fibonacci kutsub end kohtades n − 1 ja n − 2, seega x² = x + 1 ja juur on φ = 1,6180340. Hanoi kutsub end kaks korda kohas n − 1, seega x = 2 ja lahendada pole midagi.
-
Kontrolli, ära usu. Sea n 29 peale, loe väljakutsete kaarti, sea n 30 peale, loe uuesti, jaga. Trepp annab 1,83929, Fibonacci 1,61803, Hanoi täpselt 2. Viis kohta pärast koma kõigil kolmel.
-
Mida juur sulle ei anna, on kogus ise. 1,8393²⁰ on 196 331, kaart aga näitab 128 287, seega istub ees tegur 0,65; Hanoi väljakutseid on täpselt 2ⁿ⁺¹ − 1, tegur 2. Baasjuhud määravad selle konstandi ja rekurrents määrab juure, ning ainult juur otsustab, kes lõpuks võidab.
-
Lõpp jõuab siin kiiresti kätte. n = 20 juures teeb Hanoi 16,3 korda rohkem väljakutseid kui trepp ja n = 30 juures 37,8 korda rohkem. Suhe kahekordistub iga 8,3 sammu järel, sest ln 2 jagatuna ln(2 ÷ 1,8393)-ga on 8,27.
Vastus
Hanoi kasvab kiiremini, 2 versus 1,8393, ja kolmas haru ei maksa trepile midagi, mida ta endale lubada ei suudaks. Hargnemistegur on kasvukiiruse ülemine tõke ja see saavutatakse ainult siis, kui iga laps on täpselt ühe sammu võrra väiksem. Trepp kulutab kaks kolmest väljakutsest argumentidele, mis on 2 ja 3 võrra väiksemad, ja need alampuud on nii odavad, et nad ei liitu kunagi selleks haruks, mille trepp näiliselt juurde sai.
Retsept on see osa, mida hoida, sest ta töötab definitsioonil, mida keegi pole sinu eest juba lahendanud. Loenda lapsed, pane tähele, kui palju igaüks argumenti kahandab, kirjuta x suurima kahanemise astmes ülejäänud kahanemiste x-astmete summana ja võta suurim reaalarvuline juur. Üks hoiatus käib sellega kaasas: see on fakt naiivse puu kohta ja naiivne puu ei ole see, mida keegi kirjutaks. Erinevate alamülesannete kaart näitab trepi puhul n = 20 juures 21 ja Hanoi puhul samuti 21, seega kaotab memo eksponendi sootuks ja kasvukiirus lakkab midagi tähendamast. -
Õpitee