Operace nad jazyky, Vyhledávání v textu

LAB 08

B4M33PAL - Ing. David Pařil

Příklad

Automaty z minule

Nad abecedou \(\lbrace0, 1\rbrace\), jsou dány dva jazyky \(L_1\) a \(L_2\).

 

Slova \(L_1\) jsou popsána výrazem 0*1*0*1*0*,

slova \(L_2\) jsou popsána výrazem (01+10)*.

 

Sestrojte konečné automaty

  1. \(A_1\) rozpoznávající jazyk \(L_1 \cup L_2\)
  2. \(A_2\) rozpoznávající jazyk \(L_1 \cap L_2\)

Řešení

Z minulého cvičení si pamatujeme:

0*1*0*1*0*

(01+10)*

01

10

000

111

000

111

000

Takže:

\(L_1 \cup L_2\):

\(L_1 \cap L_2\):

0

1

00

11

01

10

0

1

0

1

0

1

01

10

01

01

10

10

Řešení   1. \(A_1\) rozpoznávající jazyk \(L_1 \cup L_2\)

Jazyk \(L_2\)

ε

S

ε

0

1

1

0

Jazyk \(L_1\)

0

1

0

1

0

0

1

0

1

0

1

0

1

0

Řešení   2. \(A_1\) rozpoznávající jazyk \(L_1 \cap L_2\)

0

1

0

1

0

0

1

0

1

0

1

0

1

0

1

0

0

1

0

1

1

1

0

0

0

1

1

1

0

0

0

Příklad

Detektor Nekonečných jazyků

Automat \(A_1\) rozpoznává jazyk \(L_1\), automat \(A_2\) rozpoznává jazyk \(L_2\).

 

Oba automaty mají \(n\) stavů.

Abeceda pro oba jazyky je shodná a má \(k\) znaků.

 

Jaká je asymptotická složitost algoritmu, který efektivně určí, zda jazyk \(L_1 \cap L_2\) je konečný?

Řešení

Automaty \(A_1\) a \(A_2\) mají po \(n\) stavech:

Automat pro průnik \(A_3 = \textcolor{red}{A_1} \cdot \textcolor{blue}{A_2}\) tedy má \(n^2\) stavů a až \(kn^2\) přechodů

Tj. z každého stavu až abeceda-krát přechodů

Řešení

Jazyk \(L_1 \cap L_2\) bude nekočné iff v \(A_3\) existuje cyklus, který je dosažitelný ze startovního stavu a zároveň z něj lze dosáhnout nějaký koncový stav.

Ověřujeme, zda graf přechodů \(A_3\) je acyklický, pokud jej omezíme jen na "relevantní" stavy...

Řešení

Proveď dva BFS/DFS průchody:

  1. Z počátečního stavu
    (dosažitelnost)
  2. Z koncových stavu v reverzním grafu
    (dosažitelnost od konce)

Zjistíme množinu "relevantních stavů"

Čas \(O(|V| + |E|)\)

Na podmnožině "relevantních" stavů:

  1. DFS: Každé nodě zapíšu čas otevření.
    Pokud narazím na hranu \((x,y)\), kde \(x\) i \(y\) jsou otevřené a \(t_{open}(x) < t_{open}(y)\), pak graf obsahuje cyklus.

    Nebo:
  2. Tarjanův algoritmus na hledání silně souvislých komponent: provedu dopředné DFS, každému navštívenému nodu přiřadím unikátní index. Při návratu z rekurze přiřazuji nejnižší index, na jaký lze z uzlu dosáhnout.

Jak poznám z Tar. alg. cykly?

Iff počet silně souvislých komponent \(\neq\) počet nodů, pak máme cyklus.

Řešení

Jaká je tedy asymptotická složitost?

Redukce automatů i kontrola acykličnosti může být provedena v:

\[O(|V| + |E|)\]

\(n^2\)

\(\textcolor{dimgray}{n^2}\cdot n^2\)

Nodů

Hran

pro NFA

Hran

pro DFA

Celkem tedy \(O(n^4)\) pro NFA  nebo \(O(kn^2)\) pro DFA.

\(\textcolor{dimgray}{n^2}\cdot k\)

Příklad

Automat na Hammingovu vzdálenost

V textu nad abecedou \(\lbrace a, b, c, d \rbrace\) máme určit všechny výskyty takových podřetězců, které:

  1. začínají i končí znakem \(b\) a zároveň
  2. mají od daného vzorku abbbcdabbcdab Hammingovu vzdálenost \(> 2\).

 

Navrhněte konečný nederministický automat pro řešení této úlohy.

Řešení

b

Σ\(=\lbrace a,b,c,d\rbrace\)

acd

acd

acd

abd

abc

abd

acd

acd

abd

abc

abd

acd

acd

acd

abd

abc

abd

acd

acd

abd

abc

abd

1 chyba:

2 chyby:

3+ chyby:

abcd

b

b

b

c

d

a

b

b

c

d

a

b

b

b

b

c

d

a

b

b

c

d

a

b

a

1. chyba

Σ

Σ

Σ

Σ

Σ

Σ

Σ

Σ

Σ

Σ

b

Proč nepoužít ε-přechody?

Příklad

Automat na Levenshteinovu vzdálenost

Konečný automat pro hledání v textu všech podřetězců, které mají od daného vzorku Levenshteinovu vzdálenost menší než dané \(k\), obsahuje epsilon-přechody.

 

Napište:

  1. příklad tohoto automatu pro délku vzorku \(6\) a hodnotu \(k = 3\).
  2. jak bude tento automat vypadat po odstranění všech epsilon-přechodů.

Řešení

1. Délku vzorku \(6\) a hodnota \(k = 3\)

ac

ab

bc

ac

ab

a

b

c

a

b

c

ac

ab

bc

ac

ab

b

c

a

b

c

c

a

b

c

Σ

bc

ε

ε

ε

ε

ε

ε

ε

ε

ε

ε

ε

ac

ab

bc

ac

ab

ab

bc

ac

ab

Σ

Σ

a

bc

b

ac

a

bc

bc

ε

Řešení

2. Nahrazení ε přechodu

bc

ac

ab

a

b

ac

ab

bc

b

c

c

a

ε

ε

ε

ε

ε

ε

ac

ab

ab

bc

c

a

ab

ab

a

Příklad

TODO

Dvě slova \(V\), \(W\) nad abecedou \(A\) mají redukovanou Levenshteinovu vzdálenost rovnu \(k\), pokud \(k\) je nejmenší možný počet editačních operací, po jejichž provedení ze slova \(V\) vznikne slovo \(W\).

 

Za editační operace považujeme v totmto případě pouze operace Insert a Delete.

 

Sestavte nedeterministický automat bez epsilon-přechodů, který v textu určí všechny výskyty řetězců, které mají od daného vzorku abaabacc redukovanou Levenshteinovu vzdálenost rovnou právě 2.

Příklad

Levenshteinovský trojúhelník

Označme symbolem \(d(x, y)\) Levenshteinovu vzdálenost slov \(x\) a \(y\).

 

Víme že, pro tři slova \(u\), \(v\), \(w\) platí \(d(u, v) = d_1\), \(d(v, w) = d_2\).

 

Jakých hodnot může nabývat \(d(u, w)\) v závislosti na \(d_1\), \(d_2\)?

Abeceda je pro všechna slova společná.

Řešení

Platí, že Levenshteinova vzdálenost je metrika, takže splňuje trojúhelníkovou nerovnost. Z trojúhelníkové nerovnosti dostáváme:

$$d(u,w) \leq d(u,v) + d(v,w) = d_1 + d_2$$

 

Dále ji použijeme opačně:

$$d(u,v) \leq d(u,w) + d(w,v) = d(u,w) + d_2 \Rightarrow d(u,w) \geq d_1 - d_2$$

$$d(v,w) \leq d(u,v) + d(u,w) = d_1 + d(u,w) \Rightarrow d(u,w) \geq d_2 - d_1$$

 

Takže musí platit:

$$|d_1 - d_2| \leq d(u,w) \leq d_1 + d_2 $$

Příklad

Sub-becedy

Sestrojte NKA pro nalezení v textu libovolného prvku množiny všech souvislých podřetězců vzorku

 

abcdefghijklmnopqrstuvwxzy

 

 

 

Řešení

Souvislých podřetězců je

$$26+25+...+2+1=351$$

Pro každý substring se bere automat, který přijímá jen tento řetězec.

Získáme:

$$ 1 + \sum_{k = 1}^{26} k \cdot (27-k) = 3277$$

stavů.

Řešení

Upgrade - vytvoříme NFA:

  • stavy \(q_0, q_1, ..., q_{26}\) \(\rightarrow\) 27 stavů
  • všechny kromě \(q_0\) jsou koncové
  • hrana \(q_i \rightarrow q_{i+1}\) (26 hran)
  • ke každé takové hraně ještě \(q_0 \rightarrow q_{i+1}\)
  • a self-loop v \(q_0\) (na celou abecedu)

Příklad

Leven>Ham or ham>Leven?

Označme    symbolem \(HD(v, w)\) Hammingovu vzdálenost slov \(v\) a \(w\)

nad abc. \(A\), symbolem \(LD(v, w)\) Levenshteinovu vzdálenost těchže slov.

 

Rozhodněte, který z následujících případů může nastat a pro možné případy uveďte příklad slov \(v\) a \(w\) délky alespoň 5.

  1. \(HD(v, w) < LD(v, w)\)
  2. \(HD(v, w) = LD(v, w)\)
  3. \(HD(v, w) > LD(v, w)\)

Řešení

Poznamenejme, že délka slov \(v\) a \(w\) musí být stejná, jinak by jejich Hammingova vzdálenost nebyla definována.

 

Všimněme si, že:

Z \(v\) na \(w\) můžeme přejít tak, že v každé odlišné pozici uděláme jednu záměnu. Těchto pozic je právě \(HD(v,w)\), tedy existuje posloupnost \(HD(v,w)\) editací, která z \(v\) udělá \(w\).

 

Proto vždy platí:

$$LD(v,w) \leq HD(v,w)$$

Řešení

$$LD(v,w) \leq HD(v,w)$$

  1. \(HD(v, w) < LD(v, w)\)
    Nemůže nastat
     
  2. \(HD(v, w) = LD(v, w)\)
    Možné (operace insert/delete mohou rozbít).
    Nelze dosáhnout pouze s 1 operací.
     
  3. \(HD(v, w) > LD(v, w)\)
    Možné.

Příklad

Počet modifikací SLOVA

Napište všechna slova, která mají od vzorku aba nad abecedou \(\lbrace a, b, c\rbrace\) Levenshteinovu vzdálenost rovnu

  1.  1
  2.  2

Řešení - Pro vzdálenost 1 od abba lze jednoduše odvodit všechna slova:

  1. Záměny jednoho znaku:
    1. pozice: bba, cba
    2. pozice: aaa, aca
    3. pozice: abb, abc
  2. Smazání jednoho znaku:
    ba, aa, ab
  3. Vložení jednoho znaku:
    1. aaba, baba, caba
    2. aaba, abba, acba
    3. abaa, abba, abca
    4. abaa, abab, abac

Řešení - Pro vzdálenost 2 od abba musíme již volit programové řešení:

a aa aaa aaaa aaab aaaba aaac aab aaba aabaa aabab aabac aabb aabba aabc aabca aac aaca aacaa aacab aacac aacb aacba aacc b ba baa baaa baaab baaba baac bab baba babaa babab babac babb babba babc babca bac baca bacaa bacab bacac bacb bacba bacc bb bba bbaa bbab bbaba bbac bbb bbba bbc bbca bc bca bcaa bcab bcaba bcac bcb bcba bcc bcca c ca caa caaa caaab caaba caac cab caba cabaa cabab cabac cabb cabba cabc cabca cac caca cacaa cacab cacac cacb cacba cacc cb cba cbaa cbab cbaba cbac cbb cbba cbc cbca cca ccaba ccba aba abaa abaab ababa ababb abac abba abbab abc abca abcaa abcab abcac abcb abcba abcc ac aca acaa acab acaba acb acba acc acca

def edit_distance(s1, s2):
    len1, len2 = len(s1), len(s2)
    d = [[0]*(len2+1) for _ in range(len1+1)]
    for i in range(len1+1):
        d[i][0] = i
    for j in range(len2+1):
        d[0][j] = j
    for i in range(1, len1+1):
        for j in range(1, len2+1):
            d[i][j] = min(
                d[i-1][j] + 1,
                d[i][j-1] + 1,
                d[i-1][j-1] + (0 if s1[i-1]==s2[j-1] else 1)
            )
    return d[len1][len2]

results = []

def gener(alphabet, origWord, generatedWord, distance):
    if len(generatedWord) > len(origWord) + distance:
        return
    for ch in alphabet:
        new_word = generatedWord + ch
        if edit_distance(origWord, new_word) <= distance:
            results.append(new_word)
        gener(alphabet, origWord, new_word, distance)

gener("abc", "aba", "", 2)
len(results), results

Příklad

TODO

V textu hledáme podřetězec \(Q\), který se od daného vzorku \(P\) může lišit právě jedním z následujících způsobů:

  • \(Q\) vznikl z \(P\) právě jednou operací SWAP (vzájemné prohození dvou sousedních znaků)
  • \(Q\) vznikl z \(P\) právě jednou operaci REWRITE (náhrada jednoho znaku jiným znakem abecedy)

Sestavte NKA pro hledání \(Q\), když víme, že \(P\) = abbaac, abeceda je \(\lbrace a, b, c\rbrace\).

Na
Viděnou
Za týden :)