Minimum Total Loss Rounding algorithms are quite useful for distribution problems if you need whole numbers after the distribution, as the final result of distribution.
Download Python script/module MinLossRounding_v1_Feb2019.py (version-1)
For example, you want to distribute a certain number of students to a number of available classrooms, approximately in proportion to the ground area (measured in square meter) of each classroom:
Distribute 180 students to 5 classrooms with given ground areas [25, 30, 20, 15, 35]
Sum of all given areas = 25 + 30 + 20 + 15 + 35 = 125 = sum([25, 30, 20, 15, 35])
If you distribute students to classrooms you will obtain following fractional numbers:
areas = [25, 30, 20, 15, 35]
d1 = [x*180.0/125.0 for x in areas] ([36.0, 43.2, 28.8, 21.6, 50.4])
Because there can’t be 43.2 or 28.8 students in a class, we need to round all these fractional numbers with minimum total loss, that is, with minimum total deviation from the original fractional number.
In my case, I defined rounding losses in proportionate terms. For example, proportionate round-down loss (deviation) for 43.2 is calculated by the function RoundDownLoss() as follows:
(43.2 - 43.0) / 43.2 = 0.2 / 43.2 = 0.004629629629629695
And round-up loss (deviation) by the function RoundUpLoss() as follows:
(44.0 - 43.2) / 43.2 = 0.8 / 43.2 = 0.01851851851851845
You can adjust the functions RoundDownLoss() and RoundUpLoss() if you have another concept of loss (deviation) in mind.