Untitled
unknown
plain_text
4 years ago
7.2 kB
6
Indexable
import React from 'react'; import classes from '../Lesson.module.scss'; import CodeEditor from '../../../../components/CodeEditor'; const Lesson221 = () => ( <div className={classes.root}> <h1> DIRIHLEOV PRINCIP </h1> <p className={classes.indent1x}> U ovom delu tražimo metod koji će nam omogućiti primenu algoritama za tačno podudaranje u problemu približnog podudaranja šablona P sa tekstom T. </p> <p className={classes.indent1x} /> <p className={classes.indent1x}>Počnimo od sledećeg primera:</p> <p className={classes.indent2x}> Pretpostavimo da imamo šablon P i da nam se on u tekstu T pojavljuje sa 1 promenom. Podelimo šablon P na dva dela (particije), u i v: </p> <img alt="" src="/assets/lesson221/pic1.svg" className={classes.indent3x} /> <p className={classes.indent2x}> Kako se dati šablon pojavljuje u tekstu T sa 1 promenom, a mi imamo 2 njegova dela, to bi značilo da se tačno jedan od ta dva dela mora naći u tom tekstu bez ijedne promene (jer se ta jedna promena može naći samo u jednom delu tog šablona). </p> <p className={classes.indent1x}> Princip koji smo prikazali na ovom jednostavnom primeru jeste Dirihleov princip i njegova definicija je sledeća: </p> <p className={classes.indent2x}> <span className={classes.red}>Definicija.</span> Ako imamo k predmeta koji su smešteni u k + 1 kutiju, tada postoji bar jedna kutija koja je prazna. </p> <p className={classes.indent1x}> Nakon prikaza Dirihleovog principa, posmatrajmo opštiju verziju prethodnog primera, tj. šablon P koji se pojavljuje u tekstu T sa ne više od k razlika (promena). </p> <p className={classes.indent2x}> Na sličan način kao što smo to radili i kada smo imali jednu razliku, šablon P ćemo podeliti na k + 1 particiju: </p> <img alt="" src="/assets/lesson221/pic2.svg" className={classes.indent3x} /> <p className={classes.indent2x}> Kako imamo do k razlika (promena), a k + 1 particija, prema Dirihleovom principu bar jedna od datih particija će se pojaviti u tekstu bez ijedne promene. Stoga, na svaku particiju primenjujemo algoritam za tačno podudaranje sa tekstom: </p> <img alt="" src="/assets/lesson221/pic3.svg" className={classes.indent3x} /> <p className={classes.indent2x}> Pretpostavimo da smo dobili jedno podudaranje, i to za particiju P3. Ovo će predstavljati naznaku da postoji mogućnost da će se susedne particije približno podudarati sa tekstom T. </p> <img alt="" src="/assets/lesson221/pic4.svg" className={classes.indent3x} /> <p className={classes.indent2x}> Nakon pronalaska pozicije gde se podudaranje desilo vršimo verifikaciju za preostale particije kako bismo videli da li se dati šablon P nalazi u tekstu T sa ne više od k promena: </p> <img alt="" src="/assets/lesson221/pic5.svg" className={classes.indent3x} /> <p className={classes.indent1x}> Dirihleov princip nam predstavlja most koji nam omogućava korišćenje algoritama za tačno podudaranje: </p> <img alt="" src="/assets/lesson221/pic6.svg" className={classes.indent2x} /> <h2> Implemetacije u Python-u</h2> <p className={classes.indent1x}> Koristimo Boyer-Moore algoritam za tačno podudaranje sa malom izmenom. </p> <CodeEditor code={` def BoyerMooreAlg(p, t): izlaz = set() pom = 0 m = len(p) n = len(t) losKarakter = heuristikaLosKarakter(p) pozicija_granice = [0] * (m + 1) pomeraj = [0] * (m + 1) preprocesiranje1(pomeraj, pozicija_granice, p, m) preprocesiranje2(pomeraj, pozicija_granice, p, m) while pom <= n - m: j = m - 1 while j >= 0 and p[j] == t[pom + j]: j -= 1 if j < 0: # umesto da štampamo poziciju gde se desilo podudaranje, dodajemo je u skup izlaz izlaz.add(pom) pomerajLK = (m - losKarakter[m-1][mapaKaraktera[t[pom + m]]] if pom + m < n else 1) pomerajDS = pomeraj[0] if pomerajDS >= pomerajLK: pom += pomerajDS else: pom += pomerajLK else: pomerajLosKarakter = j - losKarakter[j - 1][mapaKaraktera[t[pom + j]]] pomerajDobarSufiks = pomeraj[j+1] if pomerajDobarSufiks >= pomerajLosKarakter: pom += pomerajDobarSufiks else: pom += pomerajLosKarakter return izlaz `} customClass={classes.indent2x} /> <p className={classes.indent1x}> Sledeća funkcija vraća sve pozicije gde se dati šablon podudara sa tekstom do na n razlika. </p> <CodeEditor code={` def pribliznoPodudaranje(p, t, n): # primenjujemo Dirihleov princip duzina_particije = int(round(len(p) / (n + 1))) # skup svih pozicija gde se desilo približno podudaranje priblizna_podudaranja = set() # za svaku particiju Boyer-Moore algoritmom vraćamo skup pozicija gde se podudaranje desilo for i in range(n+1): # početak i kraj i-te pozicije start = i * duzina_particije kraj = min((i+1) * duzina_particije, len(p)) #tražimo da li imamo tačno podudaranje i-te particije sa tekstom podudaranja = BoyerMooreAlg(p[start:kraj], t) # proverimo sve pozicije gde se desilo podudaranje i-te particije for poz in podudaranja: # ako šablon ispada iz opsega teksta if poz < start or (poz - start) + len(p) > len(t): continue # brojima sva nepodudaranja koja postoje između particije koje se nalaze # pre i posle particije koja se podudara sa tekstom # i ako ne prelaze n, onda smo našli približno podudaranje šablona sa tekstom nepodudaranja = 0 for j in range (0,start): if not p[j] == t[poz - start + j]: nepodudaranja += 1 if nepodudaranja > n: break for j in range (kraj, len(p)): if not p[j] == t[poz - start + j]: nepodudaranja += 1 if nepodudaranja > n: break # ako smo imali najviše n nepodudaranja dodajemo poziciju približnog podudaranja šablona u skup if nepodudaranja <= n: priblizna_podudaranja.add(poz - start) #koristili smo skup jer on ne dozvoljava ponavljajuće vrednosti koje možemo dobiti return list(priblizna_podudaranja) `} customClass={classes.indent2x} /> <p className={classes.indent1x}>Testiramo datu funkciju na jednostavnom primeru:</p> <CodeEditor code={` p = 'AACTTG' t = 'CACTTAATTTG' print(pribliznoPodudaranje(p, t, 2)) `} result={` [0, 5]`} customClass={classes.indent2x} /> <p className={classes.indent1x}>Proveravamo tačnost:</p> <CodeEditor code={` t[0:6] `} result={` CACTTA`} customClass={classes.indent2x} /> <CodeEditor code={` t[5:11] `} result={` AATTTG`} customClass={classes.indent2x} /> </div> ); export default Lesson221;
Editor is loading...