【问题标题】:Lossless Compression for Coordinate Path Data坐标路径数据的无损压缩
【发布时间】:2014-01-03 21:21:43
【问题描述】:

我正在为一个项目集思广益,该项目将在数据库中存储大量坐标数据(纬度、经度)。这些数据的关键方面将被计算和存储,然后大部分数据将被压缩和存储。我正在寻找一种无损压缩算法来减少这些数据的存储空间。有没有(最好是常用的)算法可以很好地压缩这种类型的数据?

数据的已知属性

  • 坐标对是有序的,并且应该保留该顺序。
  • 所有数字将被限制为 5 位小数(大约 1m 精度)。
  • 坐标对代表一条路径,相邻坐标对的值可能相对接近。

示例数据

[[0.12345, 34.56789], [0.01234, 34.56754], [-0.00012, 34.56784], …]

注意:我现在不太关心语言,但我可能会在 Javascript 和 PHP 中实现这一点。

提前致谢!

【问题讨论】:

    标签: algorithm compression coordinates


    【解决方案1】:

    要扩展 barak manos 建议的 delta 编码,您应该首先将坐标编码为二进制数字而不是字符串。使用四字节有符号整数,每个整数等于您的值的 105 倍。

    然后应用增量编码,其中每个纬​​度和经度分别从前一个中减去。第一个纬度/经度保持不变。

    现在将数据分成四个平面,每个平面对应 32 位整数中的四个字节。较高的字节将大部分为零,所有的熵都在较低的字节中。您可以将数据分成块,这样您的平面就不必跨越整个数据集。

    然后应用 zlib 或 lzma 压缩。

    【讨论】:

    • 马克,你有没有建议四字节有符号整数只是为了去掉小数?为什么我应该将数据分成四个平面,以便我可以利用更高字节的行程编码?
    • 既要摆脱 ASCII 文本,又要避免浮点表示,这在此处不需要。
    • 四个平面是为了在更重要的平面上获得更好的压缩。如果高字节和低字节混合在一起,通常在一系列整数中,那么压缩器就更难利用低熵。
    • 您可以更进一步,将其分解为 32 个位平面而不是字节。然后您可以立即删除前六或七个平面(分别为经度和纬度),因为它们将始终为零。
    【解决方案2】:

    我建议您首先利用相邻符号相似的事实,并转换您的数据以减少熵。然后,将您选择的压缩算法应用于输出。

    令 IN_ARR 为原始数组,OUT_ARR 为转换后的数组(压缩输入):

    OUT_ARR[0] = IN_ARR[0]
    for i = 1 to N-1
        OUT_ARR[i] = IN_ARR[i] - IN_ARR[i-1]
    

    为简单起见,上面的伪代码是为一维坐标编写的。

    当然,你可以轻松实现二维坐标...

    当然,你必须在解压后应用逆运算:

    IN_ARR[0] = OUT_ARR[0]
    for i = 1 to N-1
        IN_ARR[i] = OUT_ARR[i] + IN_ARR[i-1]
    

    【讨论】:

    • Barak,这种技术有名字吗?
    • @Nate:基本视频压缩采用一组连续的帧(图像)并将其分为第一帧(称为 INTRA)和剩余的帧(称为 INTER)。 INTRA 帧按原样压缩,但对于每个 INTER 帧,算法首先计算与前一帧的差异(主要由零或接近零的值组成),然后压缩该差异而不是帧本身。由于差异的熵(多样性)要低得多,因此压缩率可能要高得多。
    • @Nate:当然,当差异变得很大时(例如,电影中的新场景开始时),算法会启动一组新的 INTRA/INTER。不确定这个方法的正式名称,但我上面的建议使用了相同的原理。
    【解决方案3】:

    以下是有效构建数据以充分利用数据的方法:-

    1. 首先将数据分为整数和小数两组:-

      例如:[1.23467,2.45678] => [1,2] and [23467,45678] => [1],[2],[23467],[45678]

    2. 由于您的数据似乎是随机的,因此您可以做的第一件事是压缩,不要直接将其存储为字符串,而是使用以下压缩。

    3. 纬度范围是 -90 到 +90,因此总共需要 180 个值,因此第一个值需要 log2(180) 位,即每个整数 8 位

    4. 经度范围是 -180 到 180,即 360 个值,因此 log2(360) 位是 9 位

    5. 小数为 5 位,因此需要 log2(10^5) = 17 位。

    6. 使用上述压缩,每条记录需要8+9+17*2 = 51 位,而如果使用字符串,则每条记录最多需要 2 + 3 + 5*2 = 15 个字节。

    7. 如果与字符串数据大小相比,压缩率 = 51/(15*8) = 42%

    8. 如果与浮点数据大小相比,压缩率 = 51/(2*32) = 80%。

    9. 将路径的相似部分分成 4 组,例如:-

    [[0.12345,34.56789],[0.01234,34.56754],[-0.00012,34.56784]...]

    => [0,0,-0],[34,34,34],[12345,1234,12],[56789,56754,56784]

    对单个组使用增量编码,然后应用霍夫曼编码以进一步压缩总数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-14
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 2014-09-28
      • 2014-05-18
      相关资源
      最近更新 更多