Округление списка чисел до определенного пользователем шага при сохранении их суммы - PullRequest
1 голос
/ 23 июля 2011

Я читал много постов о округлении чисел, но мне не удалось сделать то, что я хочу:

У меня есть список положительных операций. целое число без знака roundOffStep для использования определяется пользователем. У меня нет другого контроля.

Я хочу иметь возможность выполнять наиболее точное округление при сохранении суммы этих чисел или, по крайней мере, при сохранении новой суммы ниже исходной суммы.

Как бы я это сделал? Я ужасен с алгоритмами, так что это слишком сложно для меня.

Thx.

РЕДАКТИРОВАТЬ: Добавление теста:

FLOATS
   29.20
   18.25
   14.60
   8.76
   2.19

сумма = 73;

Допустим, roundOffStep = 5;

ROUNDED FLOATS
30
15
15
10
0

сумма = 70 <73 ОК </p>

1 Ответ

1 голос
/ 23 июля 2011
  1. Округлите все числа до ближайшего кратного roundOffStep обычно.
  2. Если новая сумма меньше исходной суммы, все готово.
  3. Для каждого числа, рассчитать rounded_number - original_number.Сортируйте этот список различий в порядке убывания, чтобы найти числа с наибольшей разницей.
  4. Выберите число, которое дает наибольшую разницу rounded_number - original_number, и вычтите roundOffStep из этого числа.
  5. Повторяйте шаг 4 (выбирая следующую наибольшую разницу каждый раз), пока новая сумма не станет меньше оригинала.

Этот процесс должен обеспечить, чтобы округленные числа были как можно ближе к оригиналам, без перехода к исходной сумме.

Пример, с roundOffStep = 5:

    Original Numbers  |   Rounded  |  Difference
----------------------+------------+--------------
         29.20        |     30     |     0.80
         18.25        |     20     |     1.75
         14.60        |     15     |     0.40
         8.76         |     10     |     1.24
         2.19         |     0      |    -2.19
----------------------+------------+--------------
Sum:     73           |     75     |

Сумма слишком велика, поэтому мы выбираем число, дающее наибольшую разницу (18,25, которое было округленок 20) и вычтите 5, чтобы дать 15. Теперь сумма равна 70, так что мы закончили.

...