半随机数据排序压缩问题

时间:2013-01-13 06:24:25

标签: random compression

我有this个整数序列。

它们之间的区别是随机的。但是,如果你计算每一个的差异,你可以看到它看起来有点对数函数(差异以对数方式增加)以某种方式与随机数/函数相关联。

我知道这不是一个庞大的数字,但我有数千个这样的系列(由相同的算法生成)。

我正在尝试尽可能多地压缩这些数据。我主要使用增量压缩,只能将数据压缩到原始大小的30%。

2 个答案:

答案 0 :(得分:1)

  

(由相同算法生成)

然后该算法本身可能提供最佳压缩。它是什么?

除此之外,很容易将数据降低到大约10K字节。使用可变长度整数对差异进行编码。这样的整数表示为高位等于1的字节序列(任何数量的那些包括无),后面是高位等于零的一个字节。然后连接每个字节的低七位以获得整数。最重要的位首先出现。

这具有在单个字节中编码小于128的所有值的优点。超过96%的差异小于128.通用压缩器将有效地霍夫曼编码那些字节。

将其应用于差异,然后使用gzip -9进行压缩,得到10626个字节。强制gzip算法仅使用Huffman压缩,我得到10018字节。如果我在第一个高位等于1之前剪切文件,仅使用Huffman分别压缩两个部分,然后将它们组合起来,得到9701个字节。

更新

以下是生成和解码变长整数的代码:

/* Write n as a variable-length integer to out. */
void var(unsigned long n, FILE *out)
{
    int ch;

    do {
        ch = (int)(n & 0x7f);
        n >>= 7;
        if (n)
            ch += 0x80;
        putc(ch, out);
    } while (n);
}

#define ULBITS 64   /* set to the number of bits in an unsigned long */

/* Read a variable-length integer from in, putting it in *n.  Return 0 on
   success, -1 on immediate end-of-file, -2 if end-of-file in the middle of an
   integer, or 1 on overflow of the unsigned long type. */
int unvar(unsigned long *n, FILE *in)
{
    int ch, b;
    unsigned long d;

    *n = 0;
    b = 0;
    do {
        ch = getc(in);
        if (ch == EOF)
            return b ? -2 : -1;
        if (b >= ULBITS)
            return 1;
        d = (unsigned long)(ch & 0x7f) << b;
        if ((d >> b) != (ch & 0x7f))
            return 1;
        *n += d;
        b += 7;
    } while (ch & 0x80);
    return 0;
}

答案 1 :(得分:0)

按当前存储,文件为101 KB。

如果将文件存储为32位整数序列(以二进制形式存储 - 是的,它们都足够小就可以执行此操作),这会使您降低到57 KB(14,345个整数x 4个字节)。 gzipping给你一个21 KB的文件。这已经超过了30%的边界,但我们可以做得更好!

如果您将每个连续差异存储为32位整数,则将其压缩为15 KB。

如果你想避免使用gzip,我们可以提出一些花哨的技巧。在每个差异上使用简单的Elias gamma coding生成一个14 KB的文件。但这需要一个烦人的比特流读写器,这可能是一个岔路口。

通过适当调整exp-Golomb code,您可以做得更好;我没试过。