在给定范围内找到最可压缩的向量?

时间:2012-11-30 07:32:32

标签: algorithm math compression

我减少了压缩问题,我正在努力解决以下问题:

您将获得两个n长度浮点值向量作为输入:

float64 L1, L2, ..., Ln;
float64 U1, U2, ..., Un;

所有我

0.0 <= Li <= Ui <= 1.0

(顺便说一下,n很大:~10 ^ 9)

该算法将L和U作为输入,并使用它们生成程序。

执行时,生成的程序输出n长度向量X:

float64 X1, X2, ..., Xn;

这样对所有人来说:

L1 <= Xi <= Ui

生成的程序可以输出符合这些界限的任何这样的X.

例如,生成的程序可以简单地将L存储为数组并输出它。 (注意,这将需要64n位空间来存储L,然后为程序输出一点额外的空间)

目标是生成的程序(包括数据)尽可能小,给定L和U.

例如,假设L的每个元素都小于0.3并且U的每个元素都大于0.4,而生成的程序可能只是:

for i in 1 to n
    output 0.35

哪个会很小。

有人可以建议采用策略,算法或架构来解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

这个简单的启发式算法非常快,如果边界允许非常好的压缩,它应该提供非常好的压缩:

为所有候选值准备任意(虚拟)二叉搜索树。 float64signed int64 s共享排序顺序,因此您可以随意更喜欢(更接近根)具有更多尾随零的值。

  • 对于每对边界
    • 从根开始。
    • 当前节点大于两个边界或小于两个边界,
      • 从树上下来。
    • 将当前节点附加到向量中。

对于上面提到的树,这意味着

  • 对于每对边界
    • 找到指定范围内的(唯一)数字,该数字具有尽可能少的有效位。也就是说,找到两个边界不同的第一个位;将其设置为1,将所有后续位设置为0;如果设置为1的位是符号位,请将其设置为0

然后,您可以将其提供给deflate库以进行压缩(并构建自解压存档)。


如果分析数据并构建不同的二叉搜索树,则可以实现更好的压缩。由于数据集非常大并且作为数据流到达,因此可能不可行,但这是一种启发式方法:

  • 而输出未完全定义
    • 找到适合最未定义的边界的任何值:
      • 将所有边界排序在一起:
        • 在具有较高值的​​边界之前使用较低值排序进行边界。
        • 下限在上限之前排序,具有相同的值。
        • 无法区分的界限被组合在一起。
      • 计算开放时间间隔的运行总计。
      • 选择最大的总数。上限或下限都可以。你甚至可以通过用最少的有效位分割间隔来尝试做出“明智的选择”。
    • 将此值设置为可以使用的所有位置的输出。

不是重新计算排序顺序,而是可以缓存排序顺序,只删除它,甚至缓存运行总计(或者从重新计算运行总计切换到在运行时缓存运行总计)。这不会改变结果,只会改善运行时间。