Rekursio on kohteen tai prosessin määritelmä, kuvaus, kuva tässä objektissa tai itse prosessissa, eli tilanne, jossa objekti on osa itseään. Termiä "rekursio" käytetään useilla erityisaloilla - kielitieteestä logiikkaan , mutta se löytää laajimman sovelluksen matematiikassa ja tietojenkäsittelytieteessä .
Matematiikassa rekursiolla tarkoitetaan funktioiden ja lukusarjojen määrittelytapaa : rekursiivisesti annettu funktio määrittää arvonsa viittaamalla itseensä muilla argumenteilla. Tässä tapauksessa kaksi vaihtoehtoa on mahdollista:
Toinen esimerkki rekursiosta matematiikassa on rekursiivisella kaavalla annettu numerosarja , jossa jokainen peräkkäinen termi sekvenssissä lasketaan n edellisen termin funktion tuloksena. Siten äärettömän lausekkeen avulla (joka on yhdistelmä rekursiivista kaavaa ja arvojoukkoa sarjan ensimmäisille n termille) voidaan määrittää ääretön sekvenssi.
Matemaattinen induktio liittyy läheisesti rekursioon : se on luonnollinen tapa todistaa funktioiden ominaisuudet luonnollisille lukuille , jotka on annettu rekursiivisesti niiden pienempien arvojen perusteella.
Matematiikassa niin kutsuttujen "primitiivisesti rekursiivisten" funktioiden luokkaa tarkastellaan erikseen. Primitiivisen rekursiivisen funktion määritelmä on myös rekursiivinen, se määrittelee joukon primitiivisiä funktioita ja sääntöjoukon; funktio on primitiivinen rekursiivinen, jos se voidaan esittää näiden sääntöjen mukaan muodostettuna primitiivisten rekursiivisten funktioiden yhdistelmänä.
Esimerkkejä matematiikan rekursiosta:
Ohjelmoinnissa rekursio on kutsu funktiolle ( proseduuri ) itsestään, suoraan ( yksinkertainen rekursio ) tai muiden funktioiden kautta ( kompleksi tai epäsuora rekursio ), esimerkiksi funktio kutsuu funktiota ja funktio funktiota . Sisäkkäisten funktio- tai proseduurikutsujen lukumäärää kutsutaan rekursion syvyydeksi. Rekursiivisen ohjelman avulla voit kuvata toistuvan tai jopa potentiaalisesti äärettömän laskutoimituksen ilman ohjelman osien nimenomaista toistoa ja silmukoiden käyttöä.
Rakenteellisesti rekursiivinen funktio ylimmällä tasolla on aina haarakäsky (jommankumman valinta kahdesta tai useammasta vaihtoehdosta riippuen ehdoista, jota tässä tapauksessa on tarkoituksenmukaista kutsua "rekursion lopetusehdoiksi"), jossa on kaksi tai useampi vaihtoehtoisia haaroja, joista ainakin yksi on rekursiivinen ja ainakin yksi terminaali . Rekursiivinen haara suoritetaan, kun rekursion lopetusehto on epätosi ja sisältää vähintään yhden rekursiivisen kutsun - funktion suoran tai epäsuoran kutsun itselleen. Päätehaara suoritetaan, kun rekursion lopetusehto on tosi; se palauttaa jonkin arvon ilman rekursiivista kutsua. Hyvin kirjoitetun rekursiivisen funktion on varmistettava, että rajallisen määrän rekursiivisia kutsuja jälkeen rekursion lopetusehto saavutetaan, jolloin peräkkäisten rekursiivisten kutsujen ketju katkeaa ja palaa.
Niiden toimintojen lisäksi, jotka tekevät yhden rekursiivisen kutsun jokaisessa rekursiivisessa haarassa, on olemassa tapauksia "rinnakkaisrekursiosta", joissa kaksi tai useampia rekursiivisia kutsuja tehdään samassa rekursiivisessa haarassa. Rinnakkaisrekursio on tyypillistä monimutkaisten tietorakenteiden, kuten puiden, käsittelyssä. Yksinkertaisin esimerkki rinnakkaisrekursiivisesta funktiosta on Fibonacci-sarjan laskenta, jossa n:nnen termin arvon saamiseksi on tarpeen laskea (n-1)- ja (n-2)-. .
Rekursiivisten funktiokutsujen toteutus käytännössä käytetyissä kielissä ja ohjelmointiympäristöissä perustuu pääsääntöisesti puhelupinomekanismiin - funktion paluuosoite ja paikalliset muuttujat kirjoitetaan pinoon , minkä ansiosta jokainen seuraava rekursiivinen kutsu tämä funktio käyttää omia paikallismuuttujiaan ja tästä johtuen se toimii oikein. Tämän melko yksinkertaisen mekanismin kääntöpuolena on, että jokainen rekursiivinen puhelu vaatii tietyn määrän tietokoneen RAM -muistia , ja jos rekursio on liian syvä, puhelupino voi vuotaa yli.
Kysymys rekursiivisten funktioiden käytön toivottavuudesta ohjelmoinnissa on epäselvä: toisaalta rekursiivinen muoto voi olla rakenteellisesti yksinkertaisempi ja selkeämpi, varsinkin kun toteutettu algoritmi itsessään on olennaisesti rekursiivinen. Lisäksi joillakin deklaratiivisilla tai puhtaasti toiminnallisilla kielillä (kuten Prolog tai Haskell ) ei yksinkertaisesti ole syntaktisia keinoja silmukoiden järjestämiseen, ja niiden rekursio on ainoa käytettävissä oleva mekanismi toistuvien laskelmien järjestämiseen. Toisaalta on yleensä suositeltavaa välttää rekursiivisia ohjelmia, jotka johtavat (tai joissain tilanteissa voivat johtaa) liian suureen rekursioon. Siten opetuskirjallisuudessa laajalle levinnyt esimerkki faktoriaalin rekursiivisesta laskemisesta on pikemminkin esimerkki siitä, kuinka rekursiota ei saa käyttää, koska se johtaa riittävän suureen rekursioon ja sillä on ilmeinen toteutus perinteisen syklisen muodossa. algoritmi.
On olemassa erityinen rekursio, jota kutsutaan " häntärekursioksi " (rekursiivisen algoritmin rakenne on sellainen, että rekursiivinen kutsu on viimeinen funktiossa suoritettu operaatio ja sen tulos palautetaan suoraan funktion tuloksena). Toiminnallisten ohjelmointikielten tulkit ja kääntäjät , jotka tukevat koodin optimointia (lähde tai suoritettava) muuntaa tail-rekursion automaattisesti iteraatioksi , mikä varmistaa tail-rekursio-algoritmien suorittamisen rajoitetussa muistimäärässä. Tällaiset rekursiiviset laskelmat, vaikka ne olisivat muodollisesti äärettömiä (esimerkiksi käytettäessä rekursiota käyttäjien komennot hyväksyvän kuoren työn järjestämiseen), eivät koskaan johda muistin ehtymiseen . Ohjelmointikielistandardit eivät kuitenkaan aina määrittele tarkasti, mitkä ehdot rekursiivisen funktion on täytettävä, jotta kääntäjä voi taatusti muuntaa sen iteraatioksi. Yksi harvoista poikkeuksista on Scheme-kieli ( lisp-kielen murre ) , jonka kuvaus sisältää kaikki tarvittavat tiedot.
Teoreettisesti mikä tahansa rekursiivinen funktio voidaan korvata silmukalla ja pinolla . Tällainen muutos on kuitenkin pääsääntöisesti merkityksetön, koska se johtaa vain kontekstin automaattisen tallennuksen korvaamiseen puhelupinossa samojen toimintojen manuaalisella suorittamisella samalla tai suuremmalla muistinkulutuksella. Poikkeuksena voi olla tilanne, jossa rekursiivinen algoritmi on mallinnettava kielellä, jossa rekursio on kielletty.
Toisin kuin eksplisiittisesti syklisissä ohjelmissa, ei ole tarvetta ottaa keinotekoisesti käyttöön invarianttia todistamaan rekursiivisten ohjelmien oikeellisuutta . Rekursiivisen funktion oikeellisuuden analyyttinen todistus rajoittuu matemaattisen induktion menetelmään eli seuraavien väitteiden todistukseen:
Ensimmäisen ja toisen lauseen summasta seuraa, että jos päätehaara saavutetaan (ja tämä tarkoittaa kaikissa tapauksissa, kun funktion laskenta osoittautuu lopulliseksi), funktio palauttaa oikean tuloksen. Kolmas väite todistaa, että mikä tahansa laskelma on äärellinen. Siksi mikä tahansa funktiokutsu oikeilla parametreilla palauttaa oikean tuloksen (ilmeisellä "teknisellä" varoituksella - jos rekursion syvyys ei ole niin suuri, että se aiheuttaa muistin ylivuodon).
Rekursiivinen datamäärittely tapahtuu, kun tietorakenne (tietue, objekti) sisältää sisäkkäisen objektin, joka on rakenteellisesti samanlainen kuin itse tai (useammin) viittauksen samaan objektiin. Objektin rekursiivisen määrittelyn etuna on, että tällainen äärellinen määritelmä voi kuvata mahdollisesti äärettömän tietorakenteen. Samanlaisia rakenteita käytetään kuvattaessa listoja ja kaavioita . Luettelon kuvauksen esimerkki ( C ):
struct element_of_list { struct element_of_list * next ; /* osoitin seuraavaan samantyyppiseen elementtiin */ intdata ; _ /* tietoja */ };Koska ääretön määrä sisäkkäisiä objekteja ei mahdu äärelliseen muistiin, todellisuudessa tällaiset rekursiivisesti määritellyt rakenteet ovat aina äärellisiä. Lopullisiin (pääte)soluihin kirjoitetaan yleensä tyhjiä osoittimia, jotka ovat myös lippuja, jotka osoittavat rakennetta käsittelevälle ohjelmalle, että sen loppu on saavutettu.
Rekursiivinen tietorakenne aiheuttaa usein rekursion käytön näiden tietojen käsittelyssä. Viime vuosina on yleistynyt käsite ns. " laiska arviointi ", jonka mukaan ohjelman käsittelemät tiedot lasketaan vain silloin, kun sitä tarvitaan. Tämän konseptin toteuttaminen on johtanut joissakin kielissä ( Haskell , Python ) kykyyn kuvata potentiaalisesti ääretöntä, mukaan lukien rekursiiviset sekvenssit ilman nimenomaisia rajoituksia objektien luomiselle ja työskennellä vapaasti niiden kanssa.
Klassinen esimerkki äärettömästä rekursiosta on kaksi toisiaan vastapäätä olevaa peiliä : ne muodostavat kaksi pienenevien peiliheijastusten käytävää.
Toinen esimerkki äärettömästä rekursiosta on elektronisten vahvistuspiirien itseherätys (positiivinen takaisinkytkentä) , kun signaali lähdöstä menee sisääntuloon, vahvistetaan, menee takaisin piirin sisäänmenoon ja vahvistetaan uudelleen. Vahvistimia, joille tämä toimintatapa on vakio, kutsutaan itseoskillaattoriksi .
Kielitieteessä rekursio on kielen kykyä luoda sisäkkäisiä lauseita ja rakenteita. Peruslausetta " kissa söi hiiren " voidaan laajentaa rekursiolla " Vanya arvasi, että kissa söi hiiren" , edelleen " Katia tietää, että Vanya arvasi, että kissa söi hiiren" ja niin edelleen. Rekursiota pidetään yhtenä kielellisistä universaaleista , eli se on ominaista mille tahansa luonnolliselle kielelle. Äskettäin on kuitenkin keskusteltu aktiivisesti mahdollisesta rekursion puuttumisesta yhdessä Amazonin kielistä - Pirahana , jonka kielitieteilijä Daniel Everett [1] totesi .
rekursio katso rekursio
Löysin seuraavan lyhyen tiedon:
"SEPULS ovat tärkeä elementti ardrite-sivilisaatiossa (katso) Enteropia-planeetalta (katso). Katso SEPULCARIA.
Noudatin tätä neuvoa ja luin:
"SEPULCARIA - laitteet erotteluun (q.v.)".
Etsin "Sepulenia"; siinä luki:
"MAISTUS - Ardritsien (katso) miehitys Enteropia-planeetalta (katso). Katso SEPULS.
fraktaaleja | ||
---|---|---|
Ominaisuudet | ||
Yksinkertaisimmat fraktaalit | ||
outo houkutin | Multifraktaali | |
L-järjestelmä | Tilan täyttökäyrä | |
Bifurkaatiofraktaalit | ||
Satunnaiset fraktaalit | ||
Ihmiset | ||
liittyvät aiheet |