Teoria informacji/TI Ćwiczenia 4

From Studia Informatyczne

Spis treści

Laboratorium

Zadanie 1

Polecenie

  1. Przygotuj trzy pliki, zawierające tekst w trzech różnych językach: polskim, angielskim i trzecim dowolnie wybranym. Każdy plik powinien zawierać przynajmniej 50000 znaków. Duży wybór tekstów w różnych językach można znaleźć na przykład na stronie Projektu Gutenberg.
  2. Napisz program litery, który czyta plik tekstowy o podanej nazwie (przekazanej jako parametr wywołania programu) i wypisuje wszystkie symbole występujące w pliku wraz z ich częstością w formie: A 0.134 <nowa_linia> b 0.126 ... Nie musi poprawnie wypisywać znaków narodowych. Program powinien wypisać też entropię binarną obliczonego rozkładu prawdopodobieństwa. Uruchom program dla trzech przygotowanych wcześniej plików, porównaj otrzymane wyniki.
  3. Napisz program huffman, który czyta plik tekstowy o podanej nazwie i oblicza kod Huffmana dla rozkładu symboli występujących w tym pliku. Program powinien wypisać otrzymany kod w formie: A 001 <nowa_linia> b 0001010 ...
    Napisz program shannon, który oblicza kod Shannona-Fano.
  4. Napisz program kompresuj, który koduje (kompresuje) podany plik tekstowy plik.txt za pomocą kodu Huffmana i Shannona-Fano. Wynik kodowania powinien zostać zapisany do plików plik.huf i plik.sf. Dla ułatwienia można każdy wynikowy bit zapisywać na oddzielnym bajcie, jako znak "0" lub "1".
  5. Uruchom program kompresuj dla trzech przygotowanych plików tekstowych. Dla każdego z nich porównaj następujące wielkości:
    • liczbę bitów oryginalnego pliku,
    • liczbę znaków "0"/"1" w plikach .huf i .sf,
    • entropię rozkładu prawdopodobieństwa symboli w oryginalnym pliku.
      Czy te wielkości zależą od języka kompresowanego tekstu?
  6. Napisz program kompresujbloki, który kompresuje podany plik metodą Huffmana i Shannona-Fano, zastosowanymi do bloków długości 2, 3, 4 lub więcej (tzn. kod jest generowany nie dla pojedynczych symboli, lecz dla par, trójek, czwórek ... sąsiednich symboli). Porównaj efektywność kompresji pojedynczych symboli i bloków, pod względem:
    • rozmiaru zakodowanego pliku,
    • rozmiaru kodu (aby móc w praktyce wykonać dekompresję, kod musiałby być zapisany razem z zakodowaną informacją),
    • złożoności czasowej i pamięciowej algorytmu.

Prowadzący laboratorium może zrezygnować z części zadania, np. z implementacji kodowania Shannona-Fano.

Rozwiązanie

Rozwiązanie zadania powinno zawierać:

  • wykonywalne programy,
  • kody źródłowe programów,
  • pliki tekstowe wykorzystane do eksperymentów,
  • raport z analizą otrzymanych wyników i odpowiedziami na postawione wyżej pytania.

Pliki źródłowe i raport należy podpisać imieniem i nazwiskiem autora.

Ocenie podlegać będzie poprawność implementacji oraz umiejętność analizy i interpretacji wyników eksperymentalnych. Dodatkowe programy, eksperymenty, komentarze będą mile widziane. Nie będzie natomiast brana pod uwagę efektywność czasowa i pamięciowa programów.


Zadanie 2

Wykonaj następujący eksperyment, aby sprawdzić, czy ponowna kompresja pliku już skompresowanego może pozwolić na dalsze zmniejszenie rozmiaru pliku:

  1. Przygotuj plik dane.txt zawierający tekst w języku naturalnym (polskim lub angielskim) o długości przynajmniej 50000 znaków.
  2. Skompresuj dane.txt algorytmem Huffmana, zapisując zakodowaną informację do pliku wynik.huf (możesz wykorzystać program kompresuj z zadania 1). Dla ułatwienia możesz każdy wynikowy bit zapisywać na oddzielnym bajcie, jako znak "0" lub "1".
  3. Wynikowy ciąg bitów skompresuj algorytmem Huffmana, zastosowanym do bloków 1, 2, 4, 8 i 16 bitów, otrzymując pięć kolejnych plików: wynik01.huf, wynik02.huf, wynik04.huf, wynik08.huf, wynik16.huf (możesz wykorzystać program kompresujbloki z zadania 1).

Odpowiedz na pytania:

  1. Czy poprzez powtórne zastosowanie tego samego algorytmu kodowania (tzn. algorytmu Huffmana dla bloków 1-elementowych) można osiągnąć mniejszy rozmiar pliku? Wyjaśnij dlaczego.
  2. Czy poprzez powtórne zastosowanie innego algorytmu kodowania można osiągnąć mniejszy rozmiar pliku? Wyjaśnij dlaczego.
  3. W praktyce, aby móc wykonać dekompresję, w nagłówku wynikowego pliku musiałby być też zapisany kod, użyty do zakodowania wiadomości. Wymyśl prosty i oszczędny format zapisu kodu. Oszacuj ile bajtów byłoby potrzebnych na zapisanie każdego z pięciu kodów, użytych w pkt. 3 do powtórnej kompresji.
  4. Czy powtórne zastosowanie algorytmu Huffmana, być może z innym rozmiarem bloku, może spowodować zwiększenie rozmiaru pliku z nagłówkiem, czyli łącznego rozmiaru zakodowanej wiadomości i kodu, użytego do zakodowania? Wyjaśnij dlaczego.


Zadanie 3

Wykonaj następujący eksperyment:

  1. Przygotuj plik dane.txt zawierający tekst w języku naturalnym (polskim lub angielskim) o długości przynajmniej 50000 znaków.
  2. Wygeneruj kody Huffmana \varphi_1, \varphi_2 i \varphi_3 dla bloków 1, 2 i 3 symboli pliku dane.txt.
  3. Wygeneruj losowy ciąg 10000 bitów i zapisz do pliku kod.huf.
  4. Spróbuj odczytać 1000 symboli poprzez "zdekodowanie" pliku kod.huf (tzn. przyjmując, że zawiera on zakodowaną wiadomość), używając każdego z kodów \varphi_1, \varphi_2 i \varphi_3. Wynik dekodowania zapisz do plików dekod1.txt, dekod2.txt i dekod3.txt.

Odpowiedz na pytania:

  1. Czy każdy wylosowany ciąg bitów można zdekodować za pomocą kodów Huffmana \varphi_i? A za pomocą dowolnego kodu, niekoniecznie będącego kodem Huffmana?
  2. Ile bitów pliku kod.huf musiałeś zdekodować w każdym z 3 przypadków, aby uzyskać 1000 symboli? W którym przypadku liczba bitów była największa, a w którym najmniejsza? Dlaczego są one różne dla każdego przypadku?
  3. Jak można przewidzieć te wartości bez wykonywania eksperymentu, znając jedynie kod \varphi_i? Podaj odpowiedni wzór.
  4. Który z plików dekod*.txt jest najbardziej podobny do pliku dane.txt pod względem częstości występowania poszczególnych liter lub słów?