Por que a taxa de compactação usando bzip2 para uma sequência de "a" é tão nervosa?

15
library(ggplot2)

compress <- function(str) {
  length(memCompress(paste(rep("a", str), collapse=""), type="bzip2"))
  / nchar(paste(rep("a", str), collapse=""))
}

cr <- data.frame(i = 1:10000, r = sapply(1:10000, compress))

ggplot(cr[cr$i>=5000 & cr$i<=10000,], aes(x=i, y=r)) + geom_line()

insira a descrição da imagem aqui

A taxa de compressão começa em 37 para "a" e atinge o ponto de equilíbrio em 39 "a" s (taxa de compressão = 1). O gráfico começa bastante suave e fica repentino por 98 "a" s e a partir daí em intervalos cada vez menores.

As baixas locais e seções suaves também parecem bastante erráticas e aleatórias. Alguém pode me explicar por que o bzip2 mostra esse comportamento neste exemplo?

Raffael
fonte

Respostas:

14

a(cabeçalho,"uma",n)anuma+lgnumauma+lg(n)nΘ(lg(n)p/n)p1 1

lgnnumanuma+1 1uma+2umanuma+1 1numa+2n

Como a taxa de compactação é muito próxima da taxa inversa do comprimento para observação visual, eis os dados para comprimentos pequenos na minha implementação (isso pode depender da versão da biblioteca bzip2, pois existem várias maneiras de compactar algumas entradas ) A primeira coluna indica o número de a's, a segunda coluna é o comprimento da saída compactada.

1–3       37
4–99      39
100–115   37
116–258   39
259–354   45
355       43
356       40
357–370   41
371–498   43
499–513   41
514–609   45
610       43
611       41
613–625   42
626–753   44
754–764   42
765       40
766–767   41
768       42
769–864   45
…

O Bzip2 é muito mais complexo que uma codificação simples de duração. Ele funciona em uma série de etapas, e a primeira etapa é uma etapa de codificação de execução , mas com um limite de tamanho fixo. A primeira etapa funciona da seguinte maneira: se um byte for repetido pelo menos 4 vezes, substitua os bytes após o quarto por um byte, indicando a contagem de repetições dos bytes apagados. Por exemplo,aaaaaaa é transformado em aaaa\d{3}(onde \d{003}está o caractere com valor de byte 3); aaaaé transformado para aaaa\d{0}e assim por diante. Como existem apenas 256 valores de bytes distintos, apenas as seqüências em que o byte é repetido até 259 vezes podem ser codificadas dessa maneira; se houver mais, uma nova sequência será iniciada. Além disso, a implementação de referência para em uma contagem de repetição de 252, que codifica uma sequência de 256 bytes.

uman1 1n34n258aaaa\d{252}\d{252} é a contagem de repetição, não verifiquei) é ela mesma repetida e, portanto, compactada pelas etapas subseqüentes.

aaaa\374aan=258a

n=100uma101aaaa\d{97}aaaaaan=101aA68n83

Minha análise deste exemplo está longe de ser exaustiva. Para entender outros efeitos, você teria que estudar as outras etapas da transformação: eu parei principalmente após a etapa 1 de 9. Espero que isso lhe dê uma idéia de por que as taxas de compressão ficam um pouco irregulares e não variam monotonicamente. Se você realmente deseja descobrir todos os detalhes, recomendo pegar uma implementação existente e observá-la com um depurador.

Na maioria das vezes, essas variações mínimas não são o foco principal ao projetar um algoritmo de compactação: em muitos cenários comuns, como algoritmos de uso geral ou de compactação de mídia, uma diferença de alguns bytes é irrelevante. A compactação tenta espremer tudo no nível local e tenta encadear transformações de maneira a ganhar muitas vezes enquanto raramente perde e depois não muito. No entanto, existem situações, como protocolos de comunicação para fins especiais, projetados para comunicação com baixa largura de banda, onde cada bit é importante. Outra situação em que o tamanho exato da saída é importante é quando o texto compactado é criptografado: quando um adversário pode enviar parte do texto para compactar e criptografar, variações no comprimento do texto cifrado podem revelar a parte do texto compactado e criptografado para o adversário;CRIME explorar em HTTPS .

Gilles 'SO- parar de ser mau'
fonte