ASD Ćwiczenia 13: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
m Zastępowanie tekstu – „ </math>” na „</math>”
m Zastępowanie tekstu – „<math> ” na „<math>”
 
Linia 16: Linia 16:
=='''Zadanie 2''' ==
=='''Zadanie 2''' ==


Udowodnij, że w wersji on-line algorytmu KMP mamy <math> delay = O(\log m)</math>
Udowodnij, że w wersji on-line algorytmu KMP mamy <math>delay = O(\log m)</math>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Linia 24: Linia 24:
Wystarczy wykazać, że   
Wystarczy wykazać, że   


<math> P'[i]=j,\ P'[j]=k>0\ \Rightarrow \ i\ge k+j</math>
<math>P'[i]=j,\ P'[j]=k>0\ \Rightarrow \ i\ge k+j</math>
Fakt ten wynika z lematu o okresowości i z definicji tablicy P'.
Fakt ten wynika z lematu o okresowości i z definicji tablicy P'.
  </div>
  </div>
Linia 34: Linia 34:
=='''Zadanie 3''' ==
=='''Zadanie 3''' ==


Udowodnij, że w wersji on-line algorytmu KMP mamy <math> delay = \Omega(\log m)</math>
Udowodnij, że w wersji on-line algorytmu KMP mamy <math>delay = \Omega(\log m)</math>


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
Linia 178: Linia 178:
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
<br>
<br>
By wykazać, że algorytm Oszczędny-MP wykonuje co najwyżej <math> \frac{3}{2}n</math>   
By wykazać, że algorytm Oszczędny-MP wykonuje co najwyżej <math>\frac{3}{2}n</math>   
porównań, pogrupujemy te porównania w dwie szufladki: <math> A</math>  i <math> B</math> . Pokażemy, że
porównań, pogrupujemy te porównania w dwie szufladki: <math>A</math>  i <math>B</math> . Pokażemy, że
w szufladce <math> A</math>  będzie co najwyżej <math> n</math>  porównań, a w szufladce <math> B</math>  co najwyżej <math> \frac{n}{2}</math>  porównań. Do szufladki <math> A</math>  wrzucamy:
w szufladce <math>A</math>  będzie co najwyżej <math>n</math>  porównań, a w szufladce <math>B</math>  co najwyżej <math>\frac{n}{2}</math>  porównań. Do szufladki <math>A</math>  wrzucamy:


<br>
<br>
Wszystkie udane porównania dokonane w trakcie szukania wzorca <math> x'</math> .
Wszystkie udane porównania dokonane w trakcie szukania wzorca <math>x'</math> .


<br>
<br>
Wszystkie nieudane porównania pierwszej litery wzorca <math> x'</math>  (czyli litery <math> b</math> ), dokonane w trakcie szukania wzorca <math> x'</math> .
Wszystkie nieudane porównania pierwszej litery wzorca <math>x'</math>  (czyli litery <math>b</math> ), dokonane w trakcie szukania wzorca <math>x'</math> .


<br> Wszystkie porównania początkowych liter <math> a</math> , za wyjątkiem porównań na tych pozycjach, gdzie wcześniej szukaliśmy litery <math> b</math>  (pierwszej litery wzorca <math> x'</math>) i nie znaleźliśmy jej.
<br> Wszystkie porównania początkowych liter <math>a</math> , za wyjątkiem porównań na tych pozycjach, gdzie wcześniej szukaliśmy litery <math>b</math>  (pierwszej litery wzorca <math>x'</math>) i nie znaleźliśmy jej.
<br>
<br>


Do szufladki <math> B</math>  wrzucamy wszystkie pozostałe porównania, czyli:
Do szufladki <math>B</math>  wrzucamy wszystkie pozostałe porównania, czyli:


<br>  
<br>  
Wszystkie nieudane porównania dokonane w trakcie szukania wzorca <math> x'</math> , za wyjątkiem nieudanych porównań pierwszej litery; są to nieudane porównania dokonywane w momencie, gdy znaleźliśmy już jakiś niepusty prefiks <math> x'</math> .
Wszystkie nieudane porównania dokonane w trakcie szukania wzorca <math>x'</math> , za wyjątkiem nieudanych porównań pierwszej litery; są to nieudane porównania dokonywane w momencie, gdy znaleźliśmy już jakiś niepusty prefiks <math>x'</math> .


<br> Porównania początkowych liter <math> a</math>  na tych pozycjach, gdzie wcześniej szukaliśmy litery <math> b</math>  i nie znaleźliśmy jej.
<br> Porównania początkowych liter <math>a</math>  na tych pozycjach, gdzie wcześniej szukaliśmy litery <math>b</math>  i nie znaleźliśmy jej.
<br>
<br>


Zauważmy, że w algorytmie MP pozycje tekstu, na których nigdy nie było żadnego udanego porównania to dokładnie te pozycje, na których nie udało się znaleźć pierwszej litery wzorca (lub pozycja jest pod sam koniec tekstu i nie ma już szans na znalezienie wzorca, algorytm już się zakończył).  Dodatkowo, zarówno algorytm MP jak i algorytm Oszczędny-MP ma taką właściwość, że jeśli na pewnej pozycji tekstu było udane porównanie, to ta pozycja tekstu już nigdy nie będzie porównywana (o niej ,,wiemy już wszystko'').  W związku z tym każde porównanie z szufladki <math> A</math>  wykonuje się na innej literze tekstu, czyli tych porównań jest co najwyżej <math> n</math> .
Zauważmy, że w algorytmie MP pozycje tekstu, na których nigdy nie było żadnego udanego porównania to dokładnie te pozycje, na których nie udało się znaleźć pierwszej litery wzorca (lub pozycja jest pod sam koniec tekstu i nie ma już szans na znalezienie wzorca, algorytm już się zakończył).  Dodatkowo, zarówno algorytm MP jak i algorytm Oszczędny-MP ma taką właściwość, że jeśli na pewnej pozycji tekstu było udane porównanie, to ta pozycja tekstu już nigdy nie będzie porównywana (o niej ,,wiemy już wszystko'').  W związku z tym każde porównanie z szufladki <math>A</math>  wykonuje się na innej literze tekstu, czyli tych porównań jest co najwyżej <math>n</math> .


Spójrzmy teraz, jak zmienia się wskaźnik, na jakiej pozycji szukamy teraz wzorca <math> x</math> . Zauważmy, że prefikso-sufiks słowa <math> x[1\ldots s]</math>  dla <math> s > k</math>  jest długości co najwyżej <math> s - k - 1</math>  (litery <math> a</math>  tego prefikso-sufiksu muszą się zaczynać za literą <math> b</math>  na pozycji <math> k+1</math> ). W związku z tym w momencie nieudanego porównania, które wystąpiło  gdy znaleziony już został niepusty prefiks słowa <math> x'</math> , wskaźnik ,,gdzie teraz szukamy'' przesuwa się o conajmniej <math> k+1</math> . Tak też jest, gdy znajdziemy całe słowo <math> x'</math>  ( przesuwamy się do prefikso-sufiksu słowa <math> x</math>) . Dodatkowo, każde nieudane porównanie litery <math> b</math>  z pozycji <math> k+1</math>  w słowie <math> x</math>  przesuwa wskaźnik o jeden.
Spójrzmy teraz, jak zmienia się wskaźnik, na jakiej pozycji szukamy teraz wzorca <math>x</math> . Zauważmy, że prefikso-sufiks słowa <math>x[1\ldots s]</math>  dla <math>s > k</math>  jest długości co najwyżej <math>s - k - 1</math>  (litery <math>a</math>  tego prefikso-sufiksu muszą się zaczynać za literą <math>b</math>  na pozycji <math>k+1</math> ). W związku z tym w momencie nieudanego porównania, które wystąpiło  gdy znaleziony już został niepusty prefiks słowa <math>x'</math> , wskaźnik ,,gdzie teraz szukamy'' przesuwa się o conajmniej <math>k+1</math> . Tak też jest, gdy znajdziemy całe słowo <math>x'</math>  ( przesuwamy się do prefikso-sufiksu słowa <math>x</math>) . Dodatkowo, każde nieudane porównanie litery <math>b</math>  z pozycji <math>k+1</math>  w słowie <math>x</math>  przesuwa wskaźnik o jeden.


W związku z tym:
W związku z tym:
<br>
<br>
Porównania z szufladki <math> B</math> , podpunkt <math> 1</math>  przesuwają wskaźnik o conajmniej
Porównania z szufladki <math>B</math> , podpunkt <math>1</math>  przesuwają wskaźnik o conajmniej
<math> k+1 \geq 2</math> .
<math>k+1 \geq 2</math> .


<br>
<br>
Po co najwyżej <math> k</math>  porównaniach z szufladki <math> B</math> , podpunkt <math> 2</math>  wskaźnik
Po co najwyżej <math>k</math>  porównaniach z szufladki <math>B</math> , podpunkt <math>2</math>  wskaźnik
przesunie się o conajmniej <math> k+1</math> . Dodatkowo, każde takie porównanie oznacza, że wcześniej na tym miejscu było nieudane porównanie litery <math> b</math> . Wliczając przesunięcia pochodzące od tych porównań otrzymujemy, że
przesunie się o conajmniej <math>k+1</math> . Dodatkowo, każde takie porównanie oznacza, że wcześniej na tym miejscu było nieudane porównanie litery <math>b</math> . Wliczając przesunięcia pochodzące od tych porównań otrzymujemy, że
wskaźnik przesunął się o conajmniej <math> k+1+L \geq 2L</math> , gdzie <math> L</math>  to liczba takich porównań liter <math> a</math>  w jednej próbie znalezienia wzorca <math> x</math> .
wskaźnik przesunął się o conajmniej <math>k+1+L \geq 2L</math> , gdzie <math>L</math>  to liczba takich porównań liter <math>a</math>  w jednej próbie znalezienia wzorca <math>x</math> .
<br>
<br>


Czyli każde porównanie z szufladki <math> B</math>  przesuwa aktualny wskaźnik (''gdzie teraz szukamy'') o conajmniej <math> 2</math> , czyli tych porównań jest nie więcej niż <math> \frac{n}{2}</math> .
Czyli każde porównanie z szufladki <math>B</math>  przesuwa aktualny wskaźnik (''gdzie teraz szukamy'') o conajmniej <math>2</math> , czyli tych porównań jest nie więcej niż <math>\frac{n}{2}</math> .


''(Rozwiązanie opracował Marcin Pilipczuk)''
''(Rozwiązanie opracował Marcin Pilipczuk)''
Linia 223: Linia 223:


Słowa cykliczne (de Bruijna):
Słowa cykliczne (de Bruijna):
Słowo binarne w długości dokładnie <math> 2^n</math> nazwiemy cyklicznym (słowem de Bruijna, który to wymyślił) rzędu n gdy każde słowo binarne długości n jest podsłowem słowa ww.
Słowo binarne w długości dokładnie <math>2^n</math> nazwiemy cyklicznym (słowem de Bruijna, który to wymyślił) rzędu n gdy każde słowo binarne długości n jest podsłowem słowa ww.


Następujący algorytm generuje takie słowo, co więcej jest ono leksykograficznie pierwsze spośród wszystkich możliwych
Następujący algorytm generuje takie słowo, co więcej jest ono leksykograficznie pierwsze spośród wszystkich możliwych

Aktualna wersja na dzień 10:29, 5 wrz 2023

Zadanie 1

Uzasadnij poprawność algorytmu obliczającego długość najkrótszego słowa pokrywającego dany tekst.

Rozwiązanie


Zadanie 2

Udowodnij, że w wersji on-line algorytmu KMP mamy delay=O(logm)

Rozwiązanie



Zadanie 3

Udowodnij, że w wersji on-line algorytmu KMP mamy delay=Ω(logm)

Rozwiązanie



Zadanie 4

Mamy zbiór słów, każde długości dwa, obliczyć długość minimalnego tekstu który zawiera wszystkie słowa.

Rozwiązanie



Zadanie 5

Udowodnij następującą ciekawą własność kombinatoryczną okresowości w tekstach. Niech nwd(p,q) oznacza najmniejszy wspólny dzielnik p,q.


Lemat [Lemat o okresowości]

Jeśli x ma okresy p, q oraz p+q|x|, to nwd(p,q) jest również okresem x.


Rozwiązanie


Zadanie 6

Lemat o okresowości można wzmocnić, osłabiając założenia. Udowodnij następujący lemat.

Lemat [Silny lemat o okresowości]

Jeśli x ma okresy p, q oraz p+q|x|+nwd(p,q), to nwd(p,q) jest również okresem x.

Rozwiązanie

Zadanie 7

Udowdnij poprawność algorytmu KMP realtime

Rozwiązanie

Zadanie 8

Przprowadź dokładny dowód tego, że algorytm Oszczędny KMP wykonuje co najwyżej 3/2 n porównań (schemat dowodu był już opisany w odpowiednim module)

Rozwiązanie

Zadanie 9

Słowa cykliczne (de Bruijna): Słowo binarne w długości dokładnie 2n nazwiemy cyklicznym (słowem de Bruijna, który to wymyślił) rzędu n gdy każde słowo binarne długości n jest podsłowem słowa ww.

Następujący algorytm generuje takie słowo, co więcej jest ono leksykograficznie pierwsze spośród wszystkich możliwych

Niech Cutfirst(x) oznacza obciecie x o pierwszy symbol, a Append(x,b) dopisanie litery b do słowa x na końcu.


Algorytm Słowa-Cykliczne

1 x := 1111..1 (n jedynek);

2 Z :=  ; wynik := słowo puste;

3 while istnieje b{0,1} takie, że Append(Cutfirst(x),b)Z do

4 wybierz minimalne takie b ;

5 Append(Cutfirst(x),b);

6 insert(x,Z) ;

7 Append(wynik,b);


Na przykład dla n=3 wynik = 00010111, a dla n=2 wynik = 0011


Udowodnij poprawność algorytmu.

Rozwiązanie