2016-11-23 29 views
2

我的程序維護着大約50,000個花車的數組。這些數字的總數是一個重要的數量,它必須隨着數組元素的變化而保持最新。有一個明顯的方式做到這一點,其中numbers是數組,total是他們總:維持大量花車的總數

function update_number(int index, float new_value) { 
    total += new_value - numbers[index]; 
    numbers[index] = new_value; 
} 

我關心的浮點舍入誤差導致的漂移相比,真正的總價值total的。這個問題有多少?

回答

2

最爲人熟知的用於儘可能精確地求和大量浮體的算法被稱爲Kahan summation。儘管現在的算法不是爲了允許加數改變而編寫的,但是適應它卻很簡單。計算初始和後,只要保持運行錯誤值,並通過添加前一個值的否定值並添加新值來更新總和。

不幸的是,如果很多數字都是負數,Kahan求和並不能提供很好的最壞情況保證...並且更新步驟保證會有。 (事實上​​,在足夠的更新之後,條件號會趨於零,這意味着錯誤將是無限的!)所以,雖然你可以使用卡農總和,並且你的錯誤將可能是是小的,但我個人不會它。

另一個更好的選擇是pairwise summation,它在實踐中提供了非常好的精度。在成對求和中,您遞歸地找到數組第一和第二半的成對和,然後求和結果。把它看作是一棵二叉樹,葉子上有你的數字,每個內部節點保存着它的兩個子節點的總和,而根則保存着所有樹葉的總和。

要將兩兩求和成一個可更新算法,只需保留所有樹節點即可。對於每個更新的值,更改目標葉,然後將其所有祖先重新計算回根。這隻需要每次更新需要log2(n)金額和n附加值。