Buscar

Capítulo 5 Codificação Fonte dados

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 16 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Capítulo 5 - Codificação de Fonte - Dados
A função de codificação de fonte tem por objetivo representar, na forma digital, a informação a ser transmitida. A eficiência do codificador está relacionada com a quantidade de bits utilizada para representar a informação. Quanto menos bits forem empregados, sem perda de informação, mais eficiente é o codificador. Logo, um processo de codificação de fonte eficiente inclui retirar redundâncias presentes na fonte de informação. [1: Alguns autores separam este processo em duas funções: formatação, responsável pela representação da informação, na forma digital, a ser transmitida e codificação de fonte, responsável pela retirada da redundância. ]
Neste capítulo apresentaremos um resumo do processo de codificação de fonte para os principais tipos de informação existentes: voz, vídeo e dados.
5.1. Codificação de Dados
Na nomenclatura utilizada em codificação de dados, as informações emitidas pela fonte são denominadas de símbolos. Por exemplo, em uma mensagem textual, como um e-mail, os símbolos são as letras do alfabeto, os algarismos e os sinais de pontuação.
Os códigos para codificação de dados podem ser divididos em duas categorias gerais:
Códigos de comprimento fixo: nos quais cada símbolo da fonte é representado por uma seqüência, denominada de palavra código, de comprimento fixo. Ou seja, todos os símbolos da fonte são representados pelo mesmo número de bits.
Códigos de comprimento variável: nos quais os comprimentos das palavras códigos utilizadas para representar cada símbolo emitido pela fonte variam com a probabilidade de ocorrência de cada símbolo, com os mais prováveis sendo representados com menos bits e os menos prováveis sendo representados com mais bits. 
Uma terceira abordagem, utilizada nos códigos de Lempel-Ziv, é utilizar palavras código de comprimento fixo para representar um número variável de símbolos da fonte. Ou seja, a palavra código representa seqüências, de tamanho variável, de símbolos da fonte.
Para codificação com comprimento fixo, o número de bits necessários para representar cada símbolo é o logaritmo na base dois do número de símbolos da fonte. Por exemplo, se a fonte tem 128 símbolos possíveis, são necessários sete bits para representar cada símbolo.
Um código de tamanho fixo bastante utilizado é o ASCII (American Standard Code for Information Interchange), que utiliza sete bits para representar: as letras do alfabeto (maiúsculas e minúsculas), os algarismos, os símbolos de pontuação ( ?, !, %, etc.) e alguns símbolos especiais utilizados com objetivo de controle da rede, como SOH (Start of Header), ETX (End of Text), STX (Start of Text), etc. Como exemplo, seguem representações de alguns símbolos no código ASCII: A = 1000001, a = 1100001, 5 = 0110101, % = 0100101, SOH = 0000001.
A vantagem de utilizar códigos de tamanho variável é sua maior eficiência. A utilização de códigos variáveis remonta aos primórdios das telecomunicações. O código Morse, inventado por Samuel Morse em 1884, já utilizava representações mais curtas para os símbolos mais prováveis e representações mais longas para os símbolos menos prováveis. Por exemplo, a letra “e”, muito comum nos textos em língua inglesa, era representada por um ponto (que significava um toque rápido), enquanto a letra “q”, pouco comum, era representada por traço-traço-ponto-traço (um traço era um toque mais longo).
Para ilustrar a maior eficiência dos códigos de tamanho variável, veja o exemplo da Tabela 5.1, no qual há uma fonte com apenas quatro símbolos, denominados genericamente de S0, S1, S2 e S3. A probabilidade associada a cada símbolo está expressa na segunda coluna. Um código de tamanho fixo, utilizado para representar os símbolos, está mostrado na terceira coluna e, finalmente, um código de tamanho variável está ilustrado na quarta coluna. Note que no código de tamanho variável os símbolos mais prováveis são representados por menos bits.
Tabela 5.1. - Exemplos de códigos de tamanho fixo e variável.
	Símbolo
	Probabilidade de ocorrência
	Código Fixo
	Código Variável
	S0
	0.5
	00
	0
	S1
	0.25
	01
	10
	S2
	0.125
	10
	110
	S3
	0.125
	11
	111
Para mostrar a maior eficiência do código de tamanho variável, vamos admitir que se deseje enviar um arquivo contendo 100.000 símbolos desta fonte. Se a transmissão é feita utilizando o código de tamanho fixo, teremos 100.000 vezes 2 = 200.000 bits transmitidos. Para calcular o número de bits transmitidos utilizando o código de tamanho variável, devemos antes estimar quantos símbolos de cada tipo haverá no arquivo. Como este tem 100.000 bits, em função das probabilidades de ocorrências fornecidas, esperamos encontrar 50.000 símbolos S0 (100.000 x 0,5), 25.000 símbolos S1 (100.000 x 0,25), 12.500 símbolos S2 e 12.500 símbolos S3. Logo, o número total de bits transmitidos com o código de tamanho variável é: 50.000 x 1 + 25.000 x 2 + 12.500 x 3 + 12.500 x 3 = 175.000 bits. O mesmo resultado poderia ser obtido calculando o comprimento médio das palavras códigos em cada um dos códigos considerados. No código de comprimento fixo este número é dois, pois todos os símbolos são representados por dois bits. No código de comprimento variável calculamos o comprimento médio da palavra código somando o número de bits utilizados em cada palavra código ponderado pela probabilidade de ocorrência do símbolo correspondente, ou seja: número médio de bits = 1 x 0.5 + 2 x 0.25 + 3 x 0.125 + 3 x 0.125 = 1.75 bits. Como cada símbolo é, em média, representado por 1.75 bits, precisamos de 1.75 x 100.000 símbolos = 175.000 bits para transmitir o arquivo.
Genericamente, o comprimento médio das palavras código é calculado por:
 (5.1)
onde lk representa o comprimento de cada uma das k palavras código e pk representa a probabilidade de ocorrência do símbolo correspondente à palavra código.
Comparando os resultados obtidos para os dois códigos, concluímos que a utilização do código de comprimento variável resultou em uma economia de 25.000 bits para a transmissão do arquivo. Ou seja, o arquivo pode ser enviado mais rapidamente, ocupando menos recursos da rede, com o código de tamanho variável.
Neste ponto cabe colocar as seguintes questões: Para a fonte da Tabela 5.1, é possível criar outro código de comprimento variável que resulte em um número ainda menor de bits transmitidos? Há um limite mínimo para o número médio de bits necessários para representar os símbolos de uma determinada fonte?
Para respondermos estas questões, precisamos primeiro introduzir o conceito de entropia de uma fonte, denotada por H(S). A entropia da fonte representa o valor médio da quantidade de informação associada a cada símbolo da fonte e é calculada por:
 (5.2)
onde pk é a probabilidade de ocorrência de cada um dos k símbolos da fonte.
Exemplo 5.1. Uma fonte possui alfabeto com quatro símbolos, S0 a S3. A probabilidade de ocorrência de cada símbolo é dada na Tabela 5.1, acima. Calcular a entropia da fonte.
Solução 
Aplicando diretamente a Equação 5.2
***
A segunda questão levantada acima é respondida pelo primeiro Teorema de Shannon, que estabelece que o comprimento médio das palavras código, para qualquer codificador de fonte, é limitado pela entropia da fonte, ou seja, para qualquer código de fonte, tem-se: [1]
 (5.3)
A eficiência de um codificador de fonte é definida como a relação entre a entropia da fonte e o tamanho médio de suas palavras código, ou seja:
 (5.4)
 Voltando à segunda questão levantada acima: para a fonte da Tabela 5.1, é possível criar outro código de comprimento variável que resulte em um número ainda menor de bits transmitidos? Já calculamos que o comprimento médio das palavras código é de 1.75 bits e, no Exemplo 5.1, calculamos que a entropia da fonte também é iguala 1.75 bits. Logo, a eficiência do código de comprimento variável apresentado na Tabela 5.1 é igual a um e não é possível criar outro código que consiga representar os símbolos da fonte com um número menor de bits. No entanto, devemos ressaltar que é possível criar outros códigos de tamanho variável que possuem a mesma eficiência do código apresentado na Tabela 5.1.
A título de comparação, a eficiência do código de comprimento fixo apresentado na tabela é 1.75/2 = 0.875.
A seguir apresentaremos uma breve descrição de dois códigos de comprimento variável, Código Prefixo e Código de Huffman, e também o princípio dos códigos de Lempel-Ziv. Um estudo detalhado destes e outros códigos para codificação de dados pode ser encontrado em [SAYOOD,2006] e [SALOMON,2007].
5.1.1. Códigos Prefixo
Um código é classificado como Código Prefixo se nenhuma de suas palavras código é prefixo de qualquer outra de suas palavras código. Por exemplo, sejam os códigos I e II apresentados na Tabela 5.2, a seguir, o código I é um código prefixo e o código II não é um código prefixo, pois, por exemplo, sua palavra código associada ao símbolo S3 contém as palavras associadas aos demais símbolos da fonte. 
Tabela 5.2. - Exemplos de códigos prefixo e não prefixo.
	Símbolo
	Probabilidade de ocorrência
	Código I
	Código II
	S0
	0.5
	0
	0
	S1
	0.25
	10
	01
	S2
	0.125
	110
	011
	S3
	0.125
	111
	0111
Pode-se facilmente construir um código prefixo por meio de um diagrama em árvore, utilizando o seguinte algoritmo simples:
A partir da raiz da árvore, crie dois ramos e associe o bit 0 a um dos ramos e o bit 1 ao outro .
Ao extremo do ramo associado ao bit 0 (poderia ser o bit 1), associe o símbolo mais provável da fonte.
Se resta apenas um símbolo não associado a nenhum ramo, associe este símbolo ao extremo do outro ramo e fim. Caso contrário, vá para o passo 4.
Crie dois novos ramos a partir do ramo associado ao bit 1; associe o bit 0 a um deles e o bit 1 ao outro.
Ao extremo do ramo associado ao bit 0, associe, dentre os símbolos remanescentes, o símbolo mais provável da fonte. Volte ao passo 3.
A palavra código associada a cada símbolo da fonte é construída tomando os bits associados aos ramos no caminho entre a raiz da árvore e o símbolo em questão. A Figura 5.1 ilustra a árvore de construção do código prefixo ilustrado na Tabela 5.2. Os pontos a e b ilustrados na figura são pontos intermediários auxiliares que serão úteis na descrição do exemplo de decodificação, não tendo qualquer significado específico.
Figura 5.1. – Árvore para construção do código prefixo da Tabela 5.2.
A árvore de codificação pode também ser utilizada no processo de decodificação, bastando tomar a seqüência de bits recebida e verificar o caminho percorrido na árvore. Sempre que a seqüência nos levar ao extremo de um ramo ao qual está associado um símbolo da fonte, o símbolo é decodificado e o processo é retomado com os bits restantes da seqüência.
Exemplo 5.2. O decodificador do código I da Tabela 5.2 recebe a seqüência binária 1110110010110, onde o bit mais à esquerda é o primeiro bit recebido. Quais são os símbolos decodificados?
Solução:
Partindo da raiz da árvore, o primeiro bit recebido (1) nos leva ao ponto intermediário a, o segundo bit recebido (1) nos leva ao ponto intermediário b e o terceiro bit recebido (1) nos leva ao símbolo S3. Logo, o símbolo S3 é decodificado.
A seqüência restante, ainda não decodificada, é 0110010110. Partindo novamente da raiz da árvore, o primeiro bit (0) nos leva ao símbolo S0. Logo, S0 é decodificado.
A seqüência restante é 110010110. Partindo da raiz da árvore, o primeiro bit (1) nos leva ao ponto intermediário a, o segundo bit (1) nos leva ao ponto intermediário b e o terceiro bit (0) nos leva ao símbolo S2. Logo, o símbolo S2 é decodificado.
Repetindo o processo para o restante da seqüência, 010110, encontramos os seguintes símbolos decodificados: S0, S1 e S2.
5.1.2. Códigos de Huffman
Em 1952, D. A. Huffman estabeleceu um algoritmo eficiente para criação de códigos de tamanho variável, denominados de Códigos de Huffman [2]. Estes códigos possuem larga aplicação em telecomunicações, como, por exemplo, para codificação de dados, codificação de facsimile e como parte de codificadores de vídeo. 
O algoritmo de Huffman é descrito nos seguintes passos:
Liste os símbolos da fonte, em ordem decrescente de probabilidade, em uma coluna.
Às duas menores probabilidades, associe os bits 0 e 1 (não importa qual bit a qual probabilidade).
Some as probabilidades dos dois símbolos menos prováveis. Gere uma nova coluna, em ordem decrescente de probabilidade, excluindo as duas probabilidades que foram somadas e acrescentando a soma resultante.
Volte ao passo 2 e repita o processo até que se tenha uma lista com apenas duas probabilidades.
O código para cada símbolo é definido tomando os bits ao longo do caminho (de trás para frente) percorrido pela probabilidade de cada símbolo da 1a até a última coluna.
Exemplo 5.3. Uma fonte possui alfabeto com cinco símbolos, S0 a S4. A probabilidade associada a cada símbolo é: p(So) = 0.4; p(S1) = 0.25; p(S2) = 0.2; p(S3) = 0.1; p(S4) = 0.05. Encontre um Código de Huffman para esta fonte.
Solução:
No primeiro passo do algoritmo de Huffman devemos organizar os símbolos da fonte em uma coluna, em ordem decrescente de probabilidade. O resultado é apresentado na segunda coluna (da esquerda para a direita) da Figura 5.2.
Associamos os bits 0 e 1 às duas menores probabilidades e as adicionamos: 0.05 + 0.1 = 0.15. Uma nova coluna, também em ordem decrescente de probabilidades, é organizada, excluindo as duas menores probabilidades (0.05 e 0.1) e acrescentando o resultado da soma (0.15). O resultado é apresentado na terceira coluna da Figura 5.2.
Novamente, associamos os bits 0 e 1 às duas menores probabilidades e as adicionamos: 0.15 + 0.2 = 0.35. Uma nova lista é organizada sem estas probabilidades e com o resultado da soma acrescentado. O resultado é mostrado na quarta coluna da Figura 5.3.
De novo, os bits 0 e 1 são associados às duas menores probabilidades e as mesmas são adicionadas: 0.35 + 0.25 = 0.6. A nova lista gerada só possui duas probabilidades (0.4 e 0.6). O algoritmo chega ao fim e os bits que codificam cada símbolo da fonte podem ser obtidos ao longo do caminho (de trás para frente) percorrido pela probabilidade de cada símbolo da 1a até a última coluna. A título de exemplo, os bits que codificam o símbolo S4, 0011, são destacados na Figura 5.2 dentro de uma caixa.
As palavras código associadas aos símbolos da fonte são: S0 = 1; S1 = 01; S2 = 000; S3 = 0010; S4 = 0011.
O comprimento médio das palavras código é: 1 x 0.4 + 2 x 0.25 + 3 x 0.2 + 4 x 0.1 + 4 x 0.05 = 2.1 bits.
A entropia da fonte, utilizando a Equação 5.2, é 2.04 bits. 
***
O problema com o algoritmo de Huffman, bem como o algoritmo descrito para o código prefixo, é que ambos demandam que a distribuição de probabilidade dos símbolos da fonte sejam conhecidas a priori. Ou seja, se não conhecermos a probabilidade associada a cada símbolo da fonte, não somos capazes de utilizar estes algoritmos. Na próxima seção apresentaremos uma técnica de codificação que prescinde deste conhecimento.
5.1.3. Códigos de Lempel-Ziv 
Finalmente, vale destacar outra forma de codificação que utiliza palavras de comprimento fixo para representar um número variável de símbolos da fonte. Um exemplo de um código com esta característica é o código de Lempel-Ziv, muito comum nos algoritmos de compactação de dados, como, por exemplo, os aplicativos do tipo Zip. A vantagem deste tipo de código é que ele se adapta à fonte, não sendo, portanto, necessário conhecer as estatísticas da mesma para a geração do código. 
Na codificação de Lempel-Ziv há um dicionário de símbolos cujo conteúdo é construído dinamicamente à medida que a codificação é feita, no lado do transmissor, e que a decodificação é feita, no lado do receptor. Este dicionário é armazenadoem uma memória, com cada posição contendo parte da informação (denominada subsequência, como descrito a seguir) a ser transmitida. O número de bits das palavras código define o número de posições da memória e, portanto, o tamanho do dicionário.
Há várias formas de descrever a codificação de Lempel-Ziv, vamos descrever aqui a versão conhecida como Lempel-Ziv-Welsh, cuja ideia básica é olhar para o fluxo de dados a ser transmitido como segmentos que são as menores subsequências ainda não contidas no dicionário, como descrito a seguir. Seja S* = S a menor subsequência do fluxo de dados a ser transmitido ainda não contida no dicionário. Esta subsequência pode ser dividida em duas partes: uma subsequência S, que já está armazenada no dicionário, e um símbolo , que representa o acréscimo à subsequência S para formar a subsequência S*. Ao identificar S*, o codificador armazena a mesma na primeira posição livre do dicionário e envia uma palavra código cujo valor aponta para a posição do dicionário que contém a subsequência S. 
Na versão aqui descrita, as palavras código apontam para posições do dicionário e, portanto, o número de posições do dicionário é igual a 2n, onde n é o número de bits de cada palavra código do codificador. As primeiras posições do dicionário contêm símbolos da fonte já conhecidos pelo codificador e decodificador.
No decodificador ocorre o mesmo processo de criação dinâmica do dicionário, tomando como ponto de partida o mesmo dicionário básico utilizado no codificador, só que agora a partir da sequência de palavras código recebidas e decodificadas. Ao receber uma palavra código, o decodificador olha para o dicionário e a decodifica como a subsequência contida na posição do dicionário apontada pela palavra código. Com base no primeiro símbolo desta subsequência decodificada, , e na última subsequência decodificada, S, o decodificador define a menor subsequência ainda não contida no dicionário, S* = S, e a armazena na primeira posição livre do dicionário. Logo, a última subsequência decodificada é sempre mantida em memória pelo decodificador para formar a próxima subsequência que será armazenada no dicionário. 
Para ilustrar melhor o processo de codificação e decodificação de Lempel-Ziv, seja o Exemplo 5.4, a seguir:
Exemplo 5.4: Desejamos transmitir uma seqüência de símbolos aabaabcabbaaabb..., emitidos por uma fonte cujo alfabeto de símbolos é {a, b, c}, utilizando palavras código de comprimento fixo igual a 4 bits. As três primeiras posições do dicionário, às quais estão associadas as palavras código 0000, 0001 e 0010, contém, respectivamente, os símbolos a, b e c. Há um total de 24 = 16 posições no dicionário. Logo, há possibilidade de armazenar 13 novas subsequências, pois as primeiras três posições já estão previamente armazenadas com os símbolos básicos do alfabeto da fonte.
Olhando para a sequência a ser transmitida, da esquerda para a direita, temos que o símbolo a está contido no dicionário, posição 0000, e a menor subsequência não contida no dicionário é S* = aa. Assim, os bits 0000 são transmitidos (primeiro símbolo, a, é transmitido) e a subsequência aa é armazenada na próxima posição livre do dicionário, ou seja, posição 0010. Neste ponto, os símbolos que ainda precisam ser transmitidos são abaabcabbaaabb... e o conteúdo do dicionário é:
	Posição da memória
	Sequência associada
	0000
	a
	0001
	b
	0010
	c
	0011
	aa
Olhando para a sequência abaabcabbaaabb.... verificamos que o símbolo a já está contido no dicionário e que a menor subsequência não contida no dicionário é S* = ab. Os bits 0000 são transmitidos, enviado portanto o símbolo a, e a subsequência ab é armazenada na próxima posição livre de memória: 0100. Neste ponto, os símbolos que ainda precisam ser transmitidos são baabcabbaaabb.... e o conteúdo do dicionário é:
	Posição da memória
	Subsequência associada
	0000
	a
	0001
	b
	0010
	c
	0011
	aa
	0100
	ab
Olhando agora para a sequência baabcabbaaabb... verificamos que o símbolo b já está contido no dicionário e que a menor subsequência não contida no dicionário é S* = ba. Logo, os bits 0001 são transmitidos (símbolo b) e a subsequência ba é armazenada na posição 0101. Os símbolos que ainda precisam ser transmitidos são aabcabbaaabb.... e o novo conteúdo do dicionário é:
	Posição da memória
	Subsequência associada
	0000
	a
	0001
	b
	0010
	c
	0011
	aa
	0100
	ab
	0101
	ba
Olhando para a sequência aabcabbaaabb.. verificamos que a subsequência aa já está armazenada no dicionário na posição 0011 e, portanto, estes bits são transmitidos para o envio dos símbolos aa. A menor subsequência não contida no dicionário agora é S* = aab e, portanto, esta subsequência será armazenada na posição 0110. A tabela a seguir resume este e os próximos passos:
	Sequência ainda por transmitir
	Menor subsequência não contida no dicionário (S*)
	Posição de memória em que a menor subsequência foi armazenada
	Parte de S* já contida no dicionário (S)
	Bits transmitidos correspondentes à parte de S* já contida no dicionário
	aabcabbaaabb...
	aab
	0110
	aa
	0011
	bcabbaaabb..
	bc
	0111
	b
	0001
	cabbaaabb...
	ca
	1000
	c
	0010
	abbaaabb..
	abb
	1001
	ab
	0100
	baaabb..
	baa
	1010
	ba
	0101
	aabb...
	aabb
	1011
	aab
	0110
	b...
	...
	...
	...
	...
O dicionário montado pelo codificador até este ponto é ilustrado na tabela a seguir.
	Posição da memória
	Subsequência associada
	0000
	a
	0001
	b
	0010
	c
	0011
	aa
	0100
	ab
	0101
	ba
	0110
	aab
	0111
	bc
	1000
	ca
	1001
	abb
	1010
	baa
	1011
	aabb
No decodificador ocorre o mesmo processo de criação dinâmica do dicionário, só que agora a partir da sequência de palavras código recebidas. Neste exemplo, a sequência de palavras código recebida é: 0000 0000 0001 0011 0001 0010 0100 0101 0110. O processo de decodificação se dá a partir do dicionário básico, que contém apenas as três posições iniciais, correspondentes ao alfabeto da fonte, ou seja: 
	Posição da memória
	Subsequência associada
	0000
	a
	0001
	b
	0010
	c
Ao receber a primeira palavra código, 0000, a subsequência (neste caso um símbolo da fonte) a é decodificada com base no dicionário básico pré-definido. Nenhuma nova subsequência é formada e, portanto, o dicionário não sofre qualquer alteração. A segunda palavra recebida, 0000, também é decodificada como a subsequência a. O primeiro símbolo da subsequência decodificada, = a, e a subsequência anterior formam a nova subsequência S* = aa, que é armazenada na posição 0011 do dicionário. A última subsequência decodificada, a, permanece na memória do decodificador. A próxima palavra recebida, 0001, é decodificada como a subsequência b e, forma, juntamente com a subsequência a que está na memória, a nova subsequência S* = ab, que é armazenada na posição 0100 do dicionário. A palavra código 0011 é decodificada como a subsequência aa; a última subsequência decodificada e o primeiro símbolo da subsequência que acabou de ser decodificada formam a subsequência S* = ba, que será armazenada na posição 0101 do dicionário. A próxima palavra recebida, 0001, é decodificada como a subsequência b; a nova subsequência S* é de novo formada pela subsequência que foi anteriormente decodificada, aa, e pelo primeiro símbolo da subsequência decodificada corrente, resultando em S* = aab, que será armazenada na posição 0110 do dicionário. O processo se repete até o final da sequência. A tabela a seguir ilustra todo o processo de decodificação ocorrido. Repare que os símbolos decodificados são, como era de se esperar, exatamente iguais aos símbolos originais emitidos pela fonte: aabaabcabbaaabb....
	Última subsequência decodificada (S)
	Palavra recebida
	Subsequência decodificada
	Primeiro símbolo da subsequência decodificada ()
	Nova subsequência formada 
(S* = S)
	Posição do dicionário em que S* será armazenada---
	0000
	a
	a
	---
	---
	a
	0000
	a
	a
	aa
	0011
	a
	0001
	b
	b
	ab
	0100
	b
	0011
	aa
	a
	ba
	0101
	aa
	0001
	b
	b
	aab
	0110
	b
	0010
	c
	c
	bc
	0111
	c
	0100
	ab
	a
	ca
	1000
	ab
	0101
	ba
	b
	abb
	1001
	ba
	0110
	aab
	a
	baa
	1010
	aab
	...
	...
	...
	...
	...
****
Como dissemos acima, há várias formas para descrever os códigos de Lempel-Ziv, uma forma alternativa, também de fácil entendimento, pode ser encontrada em [HAYKIN,2001].
O código de Lempel-Ziv, como pode ser observado a partir do Exemplo 5.4, só apresenta eficiência quando tem-se uma longa sequência a ser codificada. Para seqüências pequenas, como a mostrada no exemplo, o código pode, de fato, aumentar o número de bits a serem transmitidos se comparado com um codificador de tamanho fixo.

Continue navegando