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):
self.lapset = {}
self.laskuri = 0
self.todennakoisyys = 0.0
class Trie:
"""Trie-tietorakenne.
Sisältää perusoperaatioiden lisäksi Markovin ketjuille tarpeellisia toimintoja.
"""
def __init__(self):
"""Luo tyhjä trie-rakenne. Tyhjässä triessä on juurisolmu, jota ei vastaa mikään merkki."""
self.juuri = TrieSolmu()
self.todennakoisyydet_laskettu = True
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
solmu = self.juuri
for x in alkio:
if x not in solmu.lapset:
solmu.lapset[x] = TrieSolmu()
solmu = solmu.lapset[x]
#Käy läpi polun alkiota vastaavaan solmuun. Luo tarvittaessa solmuja
for merkki in alkio:
if merkki not in solmu.lapset:
solmu.lapset[merkki] = TrieSolmu()
solmu = solmu.lapset[merkki]
solmu.laskuri += 1
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:
return
kasiteltavat_solmut = [self.juuri]
#Solmut käsitellään syvyysjärjestyksessä, mutta tällä ei ole väliä
while kasiteltavat_solmut:
solmu = kasiteltavat_solmut.pop()
summa = 0
for _, x in solmu.lapset.items():
summa += x.laskuri
kasiteltavat_solmut.append(x)
for _, merkki in solmu.lapset.items():
summa += merkki.laskuri
kasiteltavat_solmut.append(merkki)
if summa:
for _, x in solmu.lapset.items():
x.todennakoisyys = x.laskuri / summa
for _, merkki in solmu.lapset.items():
merkki.todennakoisyys = merkki.laskuri / summa
self.todennakoisyydet_laskettu = True
def etsi_seuraavat(self, alkuosa):
if not self.todennakoisyydet_laskettu:
self.laske_todennakoisyydet()
"""Etsi alkuosaan sopivat viimeiset merkit ja niiden todennäköisyydet.
Palauttaa listan tupleja (tod., merkki) järjestettynä todennäköisyyden mukaan.
"""
#Funktion sisällä tarkistetaan onko laskenta tarpeellista
self.laske_todennakoisyydet()
solmu = self.juuri
for x in alkuosa:
if x not in solmu.lapset:
#Etsitään alkuosaa vastaava solmu
for merkki in alkuosa:
if merkki not in solmu.lapset:
return []
solmu = solmu.lapset[x]
solmu = solmu.lapset[merkki]
#Listaa kaikki alkuosan lapset todennäköisyyden mukaisessa järjestyksessä
vaihtoehdot = []
for x, lapsi in solmu.lapset.items():
vaihtoehdot.append((lapsi.todennakoisyys, x))
for merkki, lapsi in solmu.lapset.items():
vaihtoehdot.append((lapsi.todennakoisyys, merkki))
return sorted(vaihtoehdot, reverse=True)