Runder Vektor von Zahlen in Ganzzahlen unter Beibehaltung ihrer Summe

Wie rundet man Floats auf ganze Zahlen, während die Summe erhalten bleibt? hat die untenAntworte in Pseudocode geschrieben, der einen Vektor auf ganzzahlige Werte rundet, so dass die Summe der Elemente in unveränderter Form und der Rundungsfehler minimiert werden. Ich möchte dies effizient (d. H. Wenn möglich vektorisiert) in R implementieren.

Zum Beispiel ergibt das Runden dieser Zahlen eine andere Summe:

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

Pseudocode von @ kopierAntworte als Referen

// 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")

Antworten auf die Frage(6)

Ihre Antwort auf die Frage