How to round floats to integers while preserving their sum?, değişmeyen öğelerin toplamı ve dönüş hatası hatası en aza indirilecek şekilde bir vektörü tamsayı değerlerine yuvarlayan pseudocode ile yazılmış answer kodunun altındadır. I R. (yani mümkünse vektörlü) verimli bir şekilde uygulamak için istiyorumSayısal değerlerin tamsayılarını tamsayı olarak koruyarak toplamları
Örneğin, bu sayıları yuvarlama farklı toplam verir: referans answer den
set.seed(1)
(v <- 10 * runif(4))
# [1] 2.655087 3.721239 5.728534 9.082078
(v <- c(v, 25 - sum(v)))
# [1] 2.655087 3.721239 5.728534 9.082078 3.813063
sum(v)
# [1] 25
sum(round(v))
# [1] 26
kopyalama yalancı kod
// Temp array with same length as fn.
tempArr = Array(fn.length)
// Calculate the expected sum.
arraySum = sum(fn)
lowerSum = 0
-- Populate temp array.
for i = 1 to fn.lengthf
tempArr[i] = { result: floor(fn[i]), // Lower bound
difference: fn[i] - floor(fn[i]), // Roundoff error
index: i } // Original index
// Calculate the lower sum
lowerSum = lowerSum + tempArr[i] + lowerBound
end for
// Sort the temp array on the roundoff error
sort(tempArr, "difference")
// Now arraySum - lowerSum gives us the difference between sums of these
// arrays. tempArr is ordered in such a way that the numbers closest to the
// next one are at the top.
difference = arraySum - lowerSum
// Add 1 to those most likely to round up to the next number so that
// the difference is nullified.
for i = (tempArr.length - difference + 1) to tempArr.length
tempArr.result = tempArr.result + 1
end for
// Optionally sort the array based on the original index.
array(sort, "index")
daha basit formda
Bu çözüm benimkilerden daha hızlıyken ve istenen toplamı korurken, maalesef bu soruda talep edildiği gibi dönüş hatalarını en aza indirmez. Örneğin, "v <- c (2.655087, 3.721239, 5.728534, 9.082078, 3.813063)" ile, "smart.round", "sum (abs (smart.round (v) - v))' dönüş hatası hatası döndürür. 'DiffRound',' toplamı (abs (diffRound (v) -v)) 'nin dönüş hatası, 1.474329 iken, 1.606633 değerini döndürür. – josliber
doğrudur, genel dönüş hatası, diff yöntemi ile en aza indirilmez. Yine de sorunun güçlü bir gerekliliği olup olmadığından emin değilim. – Bulat
Orijinal soru şu fıkraları vardı: "Bu dört koşulun yerine getirildiği göz önüne alındığında, yuvarlama varyansını en aza indiren bir algoritma (toplam (([i] - fn [i])^2)) tercih edilir, ancak bu büyük bir anlaşma değildir. ." – Bulat