Untitled
unknown
plain_text
5 years ago
11 kB
11
Indexable
import React from 'react';
import classes from '../Lesson.module.scss';
import CodeEditor from '../../../../components/CodeEditor';
const Lesson2113 = () => (
<div className={classes.root}>
<h1>BOYER-MOORE ALGORITAM KAO KOMBINACIJA DVA PRAVILA</h1>
<p>
Kombinovanjem data dva pravila dobijamo Boyer-Moore algoritam. I jedno i drugo pravilo, kada
dođemo do nepodudaranja karaktera, preskaču određen broj poravnanja. Stoga, kada dođemo do
nepodudaranja karaktera, izabraćemo ono pravilo koje preskače više poravnanja.
</p>
<p>Pokažimo to na sledećem primeru:</p>
<p>PRIMER</p>
<img alt="" src="/assets/lesson2113/pic1.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic2.svg" className={classes.indent1x} />
<p className={classes.indent1x}>
Kako se nijedan karakter ne podudara (odmah na početku imamo nepodudaranje), onda ovde ne
možemo primeniti pravilo dobrog sufiksa, stoga primenjujemo pravilo lošeg karaktera:
</p>
<img alt="" src="/assets/lesson2113/pic3.svg" className={classes.indent1x} />
<p className={classes.indent1x}>
Pravilo lošeg karaktera (lk) preskače 6 poravnanja (pomera P za 7 pozicija), dok pravilo
dobrog sufiksa (ds) ne preskače nijedno poravnanje jer u ovom slučaju nije primenljivo, stoga
biramo pravilo lošeg karaktera. To ćemo kraće zapisivati:
</p>
<img alt="" src="/assets/lesson2113/pic4.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic5.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic6.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic7.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic8.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic9.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic10.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic11.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic12.svg" className={classes.indent1x} />
<img alt="" src="/assets/lesson2113/pic13.svg" className={classes.indent1x} />
<p className={classes.indent1x}>Dobijamo podudaranje na poziciji 18.</p>
<p className={classes.indent1x}>
Pošto nismo došli do kraja teksta, nastavljamo dalje. Kako se svi karakteri šablona podudaraju
sa tekstom ovde ćemo moći da primenimo samo pravilo dobrog sufiksa:
</p>
<img alt="" src="/assets/lesson2113/pic14.svg" className={classes.indent1x} />
<p className={classes.indent1x}>
Međutim kako to pomeranje prekoračuje dužinu teksta, ovde se zaustavljamo.
</p>
<p>Koliko je ovaj algoritam bolji od naivnog algoritma za tačno podudaranje?</p>
<p>
U ovom primeru, koristeći Boyer-Moore algoritam, preskočili smo ukupno 15 poravnanja za prvo
nađeno podudaranje (6+2+7):
</p>
<img alt="" src="/assets/lesson2113/pic15.svg" className={classes.indent1x} />
<p>
Ignorisali smo sledećih 11 karaktera teksta T, odnosno oni nisu učestvovali ni u kakvom
poređenju:
</p>
<img alt="" src="/assets/lesson2113/pic16.svg" className={classes.indent1x} />
<p>
Ovo nam pokazuje koliko je Boyer-Moore algoritam bolji od naivnog jer naivni neće preskočiti
nijedno poravnanje i svaki karakter teksta će proći poređenje. Samim tim, Boyer-Moore
algoritam je dosta brži, i zato ga u praksi koristimo za problem tačnog podudaranja.
</p>
<h2>Pravilo lošeg karaktera</h2>
<CodeEditor
code={`
mapaKaraktera = {'A': 0, 'C': 1,'G': 2,'T': 3}
def heuristikaLosKarakter(niska):
losKarakter = [0]*len(niska)
# Inicijalizujemo pojavljivanje svih karaktera na -1
# za svaki prefiks koji se završava na poziciji i
for i in range(len(niska)):
losKarakter[i] = [-1, -1, -1, -1]
# Popunjavamo prava poslednja pojavljivanja datih karaktera za svaki prefiks
for i in range(len(niska)):
if i > 0:
losKarakter[i][mapaKaraktera['A']] = losKarakter[i - 1][mapaKaraktera['A']]
losKarakter[i][mapaKaraktera['C']] = losKarakter[i - 1][mapaKaraktera['C']]
losKarakter[i][mapaKaraktera['G']] = losKarakter[i - 1][mapaKaraktera['G']]
losKarakter[i][mapaKaraktera['T']] = losKarakter[i - 1][mapaKaraktera['T']]
losKarakter[i][mapaKaraktera[niska[i]]] = i
return losKarakter
def pretragaLosKarakter(p, t):
'''
Funkcija pretrage koja koristi pravilo
loš karakter Boyer-Moore algoritma
'''
m = len(p)
n = len(t)
# kreiramo losKarakter listu tako što zovemo
# funkicju preprocesiranja heuristikaLosKarakter()
# za dati šablon p
losKarakter = heuristikaLosKarakter(p)
# s je pozicija gde se nalati početak šablon u odnosu na tekst
# krećemo od prvog poravnanja, tj. kad je šablon na početku teksta
pom = 0
while(pom <= n - m):
j = m - 1
# Smanjujemo indeks j od šablona
# sve dok se karakteri šablona i teksta podudaraju za trenutno s
while j >= 0 and p[j] == t[pom + j]:
j -= 1
# Ako se šablon nalazi u tekst na poziciji s,
# onda će indeks j postati -1 nakon petlje iznad
if j<0:
print("Šablon se javlja na poziciji %d" %pom)
'''
Pomeramo šablon tako da se sledeći karakter poravna
sa poslednjim pojavljivanjem tog karaktera u šablonu.
Uslov s + m < n je neophodan za slučaj da se šablon
pojavio na kraju
'''
pom += (m - losKarakter[m-1][mapaKaraktera[t[pom + m]]] if pom + m < n else 1)
else:
'''
Pomeramo šablon tako da se loš karakter iz teksta
poravna sa poslednjim pojavljivanjem tog karaktera
u tom prefiksu šablona.
'''
pom += j - losKarakter[j - 1][mapaKaraktera[t[pom + j]]]`}
customClass={classes.indent1x}
/>
<CodeEditor
code={`
# Testiramo funkciju
t = "AAGGCTAGCGGACC"
p = "AGCG"
pretragaLosKarakter(p, t) `}
result={`
Šablon se javlja na poziciji 6`}
customClass={classes.indent1x}
/>
<h2>Pravilo dobrog sufiksa</h2>
<CodeEditor
code={`
# preprocesiranje za određivanje granice sufiksa
def preprocesiranje1(pomeraj, pozicija_granice, p, m):
# m je dužina šablona
i = m
j = m + 1
pozicija_granice[i] = j
while i > 0:
while j <= m and p[i - 1] != p[j - 1]:
if pomeraj[j] == 0:
pomeraj[j] = j - i
j = pozicija_granice[j]
i -= 1
j -= 1
pozicija_granice[i] = j
# preprocesiranje za određivanje pomeraja
def preprocesiranje2(pomeraj, pozicija_granice, p, m):
j = pozicija_granice[0]
for i in range(m + 1):
if pomeraj[i] == 0:
pomeraj[i] = j
if i == j:
j = pozicija_granice[j]
def pretragaDobarSufiks(t, p):
# Pomeraj šablona u odnosu na tekst
pom = 0
m = len(p)
n = len(t)
pozicija_granice = [0] * (m + 1)
# Inicijalizujemo sve vrednosti pomeraja na 0
pomeraj = [0] * (m + 1)
# Uradimo preprocesiranje
preprocesiranje1(pomeraj, pozicija_granice, p, m)
preprocesiranje2(pomeraj, pozicija_granice, p, m)
while pom <= n - m:
j = m - 1
# Smanjujemo indeks j sve dok nam se karakteri podudaraju
while j >= 0 and p[j] == t[pom + j]:
j -= 1
# Ako se šablon nalazi na mestu pom u tekstu j će biti -1
if j < 0:
print("Šablon se javlja na poziciji %d" % pom)
pom += pomeraj[0]
else:
'''pat[i] != pat[s+j] stoga pomeramo šablon za
shift[j+1] mesta'''
pom += pomeraj[j + 1] `}
customClass={classes.indent1x}
/>
<CodeEditor
code={`
t = "AGAGATCCCTAAGACTGGATCCAGATCCGGGGATCC"
p = "GATCC"
pretragaDobarSufiks(t, p)`}
result={`
Šablon se javlja na poziciji 3
Šablon se javlja na poziciji 17
Šablon se javlja na poziciji 23
Šablon se javlja na poziciji 31`}
customClass={classes.indent1x}
/>
<h2>Boyer-Moore algoritam</h2>
<CodeEditor
code={`
def BoyerMooreAlg(p, t):
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:
print("Šablon se javlja na poziciji %d" %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
`}
customClass={classes.indent1x}
/>
<CodeEditor
code={`
t = "AGACTAAGACTGAGATCCGGGGATCC"
p = "GATCC"
BoyerMooreAlg(p, t)`}
result={`
Šablon se javlja na poziciji 13
Šablon se javlja na poziciji 21`}
customClass={classes.indent1x}
/>
<CodeEditor
code={`
t = "AGAGATCCCTAAGACTGGATCCAGATCCGGGGATCC"
p = "GATCC"
BoyerMooreAlg(p, t)`}
result={`
Šablon se javlja na poziciji 3
Šablon se javlja na poziciji 17
Šablon se javlja na poziciji 23
Šablon se javlja na poziciji 31`}
customClass={classes.indent1x}
/>
</div>
);
export default Lesson2113;Editor is loading...