簡體   English   中英

有什么辦法可以制作一組具有公差並且仍然是 O(1) 查找的浮點數?

[英]Is there any way to make a set of floats with tolerance and still O(1) lookup?

我想制作一組浮點數,但有一個轉折點:

當測試一些 float x 是否是集合 s 的成員時,如果 s 包含一些 float f 這樣我希望測試返回 true

abs(x - f) < tol

換句話說,如果集合包含接近 x 的數字,則返回 true。 否則返回假。

我想到的一種方法是將數字存儲在堆中而不是 hash 集合中,並使用近似相等規則來確定堆中是否包含接近的數字。

但是,這將花費 log(N) 時間,這還不錯,但如果存在這樣的算法,則獲得 O(1) 會很好。

有誰知道這怎么可能?

如果您對公差不是太挑剔,那么您可以將每個數字四舍五入到最接近的 tol/4 的倍數。

然后您可以使用 hash map,但是當您添加數字 x 時,添加 floor(4x/tol)、floor(4x/tol+1) 和 floor(4x/tol-1)。

當您查找數字 x 時,查找 floor(4x/tol)、floor(4x/tol+1) 和 floor(4x/tol-1)。

您肯定會在 tol/2 中找到匹配項,並且您可能會在 tol 中找到匹配項。

我有兩個想法(但絕不是最好的):

1.) 將數字的低 N 位屏蔽為全 0。 例如,如果您希望公差約為。 1E-3,加法時強制尾數低10位為0。 檢查時也是如此。

這種方法的一個警告是,當你不看的時候,真正的計算機經常會對 LSB 的尾數做一些奇怪的事情。 您存儲 x = b00111111100000000000000000000000,當您檢索它時,您會得到 0011111110000000000000000000001、001111110111111111111111111111111 等。原因很多,但它的底線仍然很脆弱。 任何依賴浮動相等性的東西都是脆弱的。

2.) 創建一個可散列的數據結構,其中分別包含來自 IEEE-754 浮點數的不同字段。 為什么要這樣做? 你問。 原因有兩個:

A.) 通過使用不是浮點數的 object,可以防止運行時將此數字視為浮點數。 我知道這應該無關緊要,但我已經看到 LSB 被破壞了很多次,即使很難說出原因,它顯然也很重要。 這克服了將 tol/4 的倍數存儲為 float的一個警告。 我喜歡將數字四舍五入為 tol 的倍數的想法。 唯一的缺點是,如果您將數字存儲為浮點數,運行時仍然會破壞 LSB,這是這個問題的最初動機。

B.) 您可以只存儲尾數的高 N MSB - 換句話說,選擇 N 使得 2**-N 代表您喜歡的相對公差。

這捕獲了舍入到 tol 的倍數的想法,但也沒有告訴運行時和/或 CPU 這是一個浮點數,從而防止 LSB 重整。

有興趣聽到其他想法、批評等。

而不是另一套,調整“關閉”的含義。

創建一個 function,將每個有限float映射到 integer。

在心里把每一個正float放在一個列表中——按值排序。 0.0 位於索引 0 處, MAX_FLOAT位於索引N處。 (對於負數可能是明智的: -MAX_FLOAT到 -0.0 映射到-N到 0。總排序

要查找 2 個float值是否“接近”,減去它們的索引並與公差進行比較。

這保持了浮點數浮點數的想法,因為容差在索引映射域中是固定的 integer,但在float域中按比例縮放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM