algorithm - How to round floats to integers while preserving their sum? -
Assume that I have an array of floating point numbers, sorted in (let's ascend) order, whose sum I want to "round" these numbers, while leaving their amounts unchanged, in other words, I am looking for an algorithm which can be used as the floating point numbers (this is the fn < Call / code>) to an array of integers (in this is) that:
- The two arrays have the same length
- The sum of the integers of the sum
N < Li> the difference between each floating-point number - Looking at the floats in sequential order (
fn [i] & lt; = fn [i + 1]), the integers will also be in sequential order (in [ I])
fn [i] and its related integer [i] is equal to 1 (or 1 if you really want) Given that those four conditions satisfied There is an algorithm which is spherical variance ( sum (([I] - fn [i]) ^ 2) ), but this is not a great deal. Example:
[0.02, 0.03, 0.05, 0.06, 0.07, 0.08, 0.0 9, 0.1, 0.11, 0.12, 0.13, 0.14] => [0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0, 1] [0.1, 0.3, 0.4, 0.4, 0.8] => [0, 0, 0, 1, 1] [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 1] [0.4, 0.4, 0.4, 0.4, 9.2, 9.2] => [0, 0, 1, 1, 9, 9] is better => [0, 0, 0, 0, 10, 10] are acceptable [0.5, 0.5, 11] ] => [0, 1, 11] is ok => [0, 0, 12] is not technically permitted but I want to take it in a pinch
To answer excellent questions:
- Repeated elements are available in both arrays. (Although I would be interested in listening to the algorithm which is only made when float does not join the array, it repeats)
- There is no single correct answer - Floats For a given input array, there are generally many arrays of intets that satisfy the four conditions.
- - And it's weird - Issue distribution for the top finisher in the game of MarianaCart ;-) Actually the game itself did not play, but seeing someone else I saw that 24 points of distribution from the top 4 financiers Used one, and I was surprised that it may be possible to distribute points according to the time of finishing (so if a large CD ends with it, they get a bigger share of points). This game tracks the totals as an integer, so this type of rounding is required.
For the curious, here I identify which algorithm works.
There is an algorithm that should complete the task. The main difference in the other algorithm is that it makes a number always round in the right order. Minimize the goalkeep error.
The language is some pseudo language that is probably taken from JavaScript or Lua. The point should be understood, note one based indexing (which is good with loop x for y.P)
// fn with equal length TempArr = Array (fn.length) // Calculate the required amount ArraySum = sum (fn) Lower comma = 0 - Populate the Temp Array I = 1 to fn.lengthf tempArr [i] = {Result: Floor (fn [i ], // Less bound difference: fn [i] - floor (fn [i]), // goaloff error index: i} // original index // Calculate less amount less sum = lowest join + tempArr [i] . Sort the temp arrays on the ending end / roundoff error type (tempArr, "difference") // Now the arraySum - lowerSum gives us the difference between the amount of these // arrays TempArr is ordered in such a way that the next The nearest number of numbers is at the top difference = arraySum - lowerSum // Add 1 to those people with the possibility of reaching the next number, so that the // difference varies. Sorted alternately, based on the original index, at the end of tempArr.length tempArr.result = tempArr.result + 1 for I = (tempArr.length - difference + 1). Array (sort, "index")
Comments
Post a Comment