Eu tenho um arquivo que contém números binários ordenados de a :2 n - 1
0000000000
0000000001
0000000010
0000000011
0000000100
...
1111111111
7z não compactou esse arquivo com muita eficiência (para n = 20, 22 MB foram compactados para 300 kB).
Existem algoritmos que podem reconhecer uma estrutura muito simples de dados e compactar arquivos em vários bytes? Também quero saber qual área de CS ou teoria da informação estuda tais algoritmos inteligentes. A "IA" seria muito ampla. Sugira palavras-chave mais concretas.
A noção de simetria deve desempenhar um papel fundamental na compactação de dados, mas as consultas de pesquisa "simetria na compactação de dados" e "teoria dos grupos na compactação de dados" surpreendentemente retornam quase nada relevante.
information-theory
data-compression
DSblizzard
fonte
fonte
Respostas:
Esse parece ser um caso de uso claro para a compactação delta . Se for conhecido a priori, isso é trivial: armazene o primeiro número literalmente e, para cada próximo número, armazene apenas a diferença em relação ao anterior. No seu caso, isso darán
Com a codificação simples de duração da execução, isso pode ser armazenado no espaço , pois existem apenas grupos (ou seja, dois) de deltas diferentes.O ( 1 )O (n) O (1)
Se não for conhecido, a coisa mais simples seria uma pesquisa de força bruta pelo tamanho da palavra para o qual essa representação delta / comprimento de execução fica mais curta. Talvez faça apenas essa busca por pedaços do tamanho escolhidos aleatoriamente , para amortizar a sobrecarga de encontrar , mantendo uma boa confiabilidade.√n nN--√ n
Diferentemente da proposta “tudo ou nada” da DW, a compactação delta com codificação de duração da execução pode realmente fornecer taxas de compactação sensatas para alguns tipos simples de conteúdo do mundo real, como áudio de baixa resolução. (Portanto, é adequado para compactação de áudio de baixa qualidade, latência muito baixa e baixa potência.)
fonte
Claro, claro que existem algoritmos. Aqui está o meu algoritmo:
Primeiro, verifique se o arquivo contém números binários ordenados de a 2 n - 1 , para alguns n . Nesse caso, escreva um bit 0 seguido de n um bit seguido por um bit 0.0 0 2n- 1 n n
Caso contrário, escreva um bit e, em seguida, escreva a compactação 7z do arquivo.
Isso é extremamente eficiente para arquivos dessa estrutura específica.
O ponto é: não há almoço grátis na compactação de dados. Você poderá criar um algoritmo de compactação que comprima bem um tipo de arquivo, com o custo de compactar outros piores. Mas, se você sabe a priori algo sobre a natureza dos arquivos que estará compactando, poderá otimizar seu algoritmo para esse tipo específico de arquivo.
A área é "compactação de dados". Veja nossa tag de compactação de dados e leia os livros sobre compactação de dados.
fonte
Qualquer coisa usando um BWT (transformação Burrows – Wheeler) deve ser capaz de compactar isso muito bem.
Meu teste rápido do Python:
(Os números aqui são 'first_compressor second_compressor time_taken bytes_out')
(BWT retirado daqui )
Isso ainda é 'não apenas alguns bytes', mas ainda assim é muito melhor do que apenas o gzip. BWT + bz2 reduz para 237 bytes de 1114111 para uma entrada de 16 bits, por exemplo.
Infelizmente, os BWTs são muito lentos e precisam de memória para muitos aplicativos. Especialmente considerando que essa é uma implementação ingênua em Python - na minha máquina, fico sem memória RAM antes de 2 ** 20.
Com o Pypy, eu fui capaz de executar a entrada 2 ** 20 completa e a compactou para 2611 bytes com um BWT seguido por bz2. Mas demorando mais de 3 minutos e atingindo mais de 4 GB de RAM usado ...
Infelizmente, essa abordagem ainda é um espaço de saída O (2 ^ n), ao que parece - pelo menos a partir do ajuste de curva 1..20.
fonte
eval
fazendo:for first in (bwt_c, nothing, lzma, zlib, gzip, bz2):
efOut = first.compress(inputData)
.4 times block size
memória (por exemplo, ~ 4 MB para isso) e em velocidades de>10 MB/s
(eu sou o autor de um algoritmo de compactação / biblioteca do bwt), que é bastante utilizável para muitas aplicações. Note que mesmo o gzip produz resultados compressíveis muito bons. Obrigado por compartilhar. Não conheço nenhuma pesquisa sobre o uso do bwt duas vezes.A codificação PNG faz exatamente o que você deseja. Também funciona com dados da vida real, não apenas com dados extremamente organizados.
Em PNG, cada linha é codificada com um filtro, dos quais 4 são especificados. Uma delas é "codificar esse pixel como a diferença entre seu valor e o valor do pixel acima dele". Após a filtragem, os dados são compactados usando DEFLATE.
Essa filtragem é um exemplo específico da codificação delta mencionada por leftaroundabout em sua resposta, exceto que, em vez de segui-la com a codificação de comprimento de execução, você segue com o algoritmo DEFLATE mais poderoso. Ele atinge o mesmo objetivo, apenas o DEFLATE manipulará uma variedade maior de entradas, enquanto ainda fornece as taxas de compactação desejáveis.
Outra ferramenta que é frequentemente usada em dados científicos em que o filtro simples + DEFLATE não é tão eficaz é a codificação RICE. No RICE, você pega um bloco de valores e gera todos os bits mais significativos primeiro e depois os segundos bits mais significativos, até os bits menos significativos. Você então comprime o resultado. Para seus dados que não serão tão eficazes quanto a filtragem no estilo PNG (porque seus dados são perfeitos para a filtragem PNG), mas para muitos dados científicos, eles tendem a levar a bons resultados. Em muitos dados científicos, vemos que o bit mais significativo tende a mudar lentamente, enquanto o menos significativo é quase aleatório. Isso separa os dados altamente previsíveis dos dados altamente entrópicos.
fonte
Qualquer algoritmo prático que procure estruturas específicas seria limitado apenas às estruturas codificadas nele. Você poderia corrigir o 7z para reconhecer essa sequência específica, mas com que frequência essa estrutura específica ocorrerá na vida real? Não é suficiente o suficiente para garantir o tempo necessário para verificar as entradas dessa entrada.
Praticamente à parte, pode-se conceber o compressor perfeito como um algoritmo que tenta construir o programa mais curto que produz uma determinada saída. Escusado será dizer que não há maneiras práticas de fazer isso. Mesmo que você tenha tentado uma enumeração de força bruta de todos os programas possíveis e verificado se eles produziram a saída desejada ( não é uma ideia totalmente insana ), você encontrará o problema da parada , o que significa que terá que abortar as execuções de teste após um certo número das etapas de execução, antes que você saiba se esse programa definitivamente não pode produzir a saída desejada.
A árvore de pesquisa para uma abordagem de força bruta cresce exponencialmente com a duração do programa e não é prática para todos, exceto para os programas mais simples (algo como 5 a 7 instruções).
fonte
As taxas de compressão dependem inteiramente do descompressor alvo. Se o descompactador não puder decodificar números sequenciais de 4 bytes de forma mais compacta que 4 bytes por número, você será o SOL.
Existem várias coisas que permitiriam a codificação de números seqüenciais. Por exemplo, uma codificação diferencial. Você pega n bytes de cada vez e, em seguida, pega a diferença ou o xor dos bits e compacta o resultado. Isso adiciona quatro opções aqui para tentar para cada contagem de bytes: identidade
a'[i] = a[i]
; diferençaa'[i] = a[i-1]-a[i]
; diferença inversaa'[i] = a[i]-a[i-1]
; e o xora'[i] = a[i]^a[i-1]
. Isso significa adicionar 2 bits para selecionar os métodos e uma contagem de bytes para 3 de 4 opções.No entanto, nem todos os dados são uma sequência dos registros de comprimento fixo. A codificação diferencial não faz sentido para isso (a menos que o compressor possa empiricamente provar que funciona para um pouco de dados).
fonte