1
0
Fork 0

Kommentoi trie.py tiedosto

This commit is contained in:
Vili Sinervä 2022-09-16 13:23:16 +03:00
parent 5299d616f0
commit fc4e69dfa9

View file

@ -1,55 +1,84 @@
class TrieSolmu: """Markovin ketjuille tarkoitettu trie-tietorakenteen implementaatio.
import Trie
"""
class TrieSolmu: # pylint: disable=too-few-public-methods
"""Yksittäinen trie-tietorakenteen solmu. Sisältää Markovin ketjuille tarpeellisia tietoja."""
def __init__(self): def __init__(self):
self.lapset = {} self.lapset = {}
self.laskuri = 0 self.laskuri = 0
self.todennakoisyys = 0.0 self.todennakoisyys = 0.0
class Trie: class Trie:
"""Trie-tietorakenne.
Sisältää perusoperaatioiden lisäksi Markovin ketjuille tarpeellisia toimintoja.
"""
def __init__(self): def __init__(self):
"""Luo tyhjä trie-rakenne. Tyhjässä triessä on juurisolmu, jota ei vastaa mikään merkki."""
self.juuri = TrieSolmu() self.juuri = TrieSolmu()
self.todennakoisyydet_laskettu = True self.todennakoisyydet_laskettu = True
def lisaa(self, alkio): def lisaa(self, alkio):
"""Lisää alkio triehen.
Luo tarvittavat solmut ja kasvata alkiota vastaavan solmun laskuria yhdellä.
"""
#Kertoo, että todennäköisyydet tulee laskea uudestaan
self.todennakoisyydet_laskettu = False self.todennakoisyydet_laskettu = False
solmu = self.juuri solmu = self.juuri
for x in alkio: #Käy läpi polun alkiota vastaavaan solmuun. Luo tarvittaessa solmuja
if x not in solmu.lapset: for merkki in alkio:
solmu.lapset[x] = TrieSolmu() if merkki not in solmu.lapset:
solmu = solmu.lapset[x] solmu.lapset[merkki] = TrieSolmu()
solmu = solmu.lapset[merkki]
solmu.laskuri += 1 solmu.laskuri += 1
def laske_todennakoisyydet(self): def laske_todennakoisyydet(self):
"""Laske solmujen lapsille todennäköisyys, kuinka todennäköisesti lasta vastaava merkki
ilmenee kun muut merkit on jo nähty.
"""
#Laskenta tehdään, vain jos se on tarpeellista.
if self.todennakoisyydet_laskettu: if self.todennakoisyydet_laskettu:
return return
kasiteltavat_solmut = [self.juuri] kasiteltavat_solmut = [self.juuri]
#Solmut käsitellään syvyysjärjestyksessä, mutta tällä ei ole väliä
while kasiteltavat_solmut: while kasiteltavat_solmut:
solmu = kasiteltavat_solmut.pop() solmu = kasiteltavat_solmut.pop()
summa = 0 summa = 0
for _, x in solmu.lapset.items(): for _, merkki in solmu.lapset.items():
summa += x.laskuri summa += merkki.laskuri
kasiteltavat_solmut.append(x) kasiteltavat_solmut.append(merkki)
if summa: if summa:
for _, x in solmu.lapset.items(): for _, merkki in solmu.lapset.items():
x.todennakoisyys = x.laskuri / summa merkki.todennakoisyys = merkki.laskuri / summa
self.todennakoisyydet_laskettu = True self.todennakoisyydet_laskettu = True
def etsi_seuraavat(self, alkuosa): def etsi_seuraavat(self, alkuosa):
if not self.todennakoisyydet_laskettu: """Etsi alkuosaan sopivat viimeiset merkit ja niiden todennäköisyydet.
self.laske_todennakoisyydet() Palauttaa listan tupleja (tod., merkki) järjestettynä todennäköisyyden mukaan.
"""
#Funktion sisällä tarkistetaan onko laskenta tarpeellista
self.laske_todennakoisyydet()
solmu = self.juuri solmu = self.juuri
for x in alkuosa: #Etsitään alkuosaa vastaava solmu
if x not in solmu.lapset: for merkki in alkuosa:
if merkki not in solmu.lapset:
return [] return []
solmu = solmu.lapset[x] solmu = solmu.lapset[merkki]
#Listaa kaikki alkuosan lapset todennäköisyyden mukaisessa järjestyksessä
vaihtoehdot = [] vaihtoehdot = []
for x, lapsi in solmu.lapset.items(): for merkki, lapsi in solmu.lapset.items():
vaihtoehdot.append((lapsi.todennakoisyys, x)) vaihtoehdot.append((lapsi.todennakoisyys, merkki))
return sorted(vaihtoehdot, reverse=True) return sorted(vaihtoehdot, reverse=True)