2013-09-23 176 views
1

我目前有一個應用程序需要我以儘可能少的位數發送數據。例如,如果我以度數給出方向,那麼範圍是0-359。這意味着9位,我有一個數字爲0 - 511,分辨率爲1.將會有152個可能結果的「浪費」。我可以將這些可能的結果用於錯誤處理,但我想知道是否有任何方法可用於打包更多數據。自定義數據類型壓縮

我唯一的想法是我可以添加359/511的倍增因子,這樣我就可以更精確地擠壓一下。

編輯:其他信息:

  1. 應當假定,並非所有的信息將通過

一些字段的例子得到:

方向基(360) 日基座(366 ) 小時基數(24) 分鐘基數(60)

機智h這三個例子的總浪費結果是905.

+0

輸入整數或浮點以?開頭嗎?你是否更關心無損或儘可能少使用?連續的讀數是否可能相似(或以某種方式相關)? – NPE

+0

我認爲你正在使用三角洲?這將大大減少消息的大小,但是你不得不假設一條有損線路,而不是所有消息都能通過。 – Richard

+0

我真正需要的是我們需要更多信息才能提供有意義的建議。 – NPE

回答

2

對於一個數字,你顯然不能少於9位,所以你不能做得更好。但對於多個號碼,你可以做得更好。兩件事情浮現在腦海中:

您可以同時在基地360在這裏發射多個號碼是如何編碼和三個數字:

int encoded = num0 + 360 * num1 + 360 * 360 * num2; 
var decoded0 = encoded/1 % 360; 
var decoded1 = encoded/360 % 360; 
var decoded2 = encoded/360/360 % 360; 

如果你使用一個BigInteger你可以實現理論上最佳的在無限(或實際上非常多)數字的情況下以這種方式進行編碼。

或者,您可以使用arithmetic coding的變體,該變體支持2個以上的替代方案。通過算術編碼,您可以遞增編碼數字,並在數據可用時提取數據。你只需要不斷的記憶。

如果你的數字不是均勻分佈的(比如0的可能性是平常的兩倍),算術編碼器可以使用這些知識來保存更多的位。許多通用壓縮機使用這種技術(其中LZMA)。

+1

如果在給定的時間間隔內假設均勻分佈,那麼這是最佳解決方案。我也看到這種技術在「最佳位打包」的名稱下:http://codeplea.com/optimal-bit-packing –

+0

@ usr,好主意,但如果我發送不同的基礎數據會怎麼樣。例如小時(base24),天(base366)等 – Richard

+0

@Richard,那麼你會使用一個不同於360的基礎,我猜...這可能嗎?算術代碼可以使用多個基地順便說一句。你可以使用base 360​​作爲第一個數字,使用base 24作爲第二個數字,依此類推。 – usr

0

對於您給出的「方向基(360)日基(366)小時基(24)分鐘基(60)」的特定示例,事實證明其中兩個非常適合55位。 (360 x 366 x 24 x 60)只是一個小於2的污點。因此,編碼和解碼只需使用乘法和除法(分別獲得商和餘數)。這可以用64位算術完成,所以不需要大的整數例程。實際上,55位中只有0.001位被浪費了!

因此,對於範圍爲1..360,1..366,1..24和0..59的direction:day:hour:minute,則序列{a:b:c:d, e:f:g:h}編碼爲(((((((a - 1) * 366 + (b - 1)) * 24 + (c - 1)) * 60 + d) * 360 + (e - 1)) * 366 + (f - 1)) * 24 + (g - 1)) * 60 + h。解碼需要60的餘下部分得到h。取這個商數,然後除以24的餘數得到g - 1,依此類推。

然後,55位序列可以連接成一個位流,其中八個連接55個字節。

未使用的55位序列可用於終止序列。例如。所有1位,除最後一位之外的所有1位都是零,等等。可以使用兩個不同的終結符來指示倒數第二個55位序列是否包含一個或兩個向量。

要做得更好的唯一方法是利用數字上的非均勻分佈和/或連續向量之間的相關性。對於後者,您應該考慮這些數字中的部分或全部數字是否可能與先前矢量中的相應數字接近或相同。如果存在這樣的相關性,那麼您可以發送差異,並進行一些壓縮,從而大大減少所需的比特總數。