Я хотел бы преобразовать массив чисел с плавающей точкой в массив целых чисел.Целочисленные значения должны суммироваться до заданного значения, а их значения должны быть аналогичны масштабированному входному массиву.
Другими словами, идеальный результат рассчитывается по input_float / sum_of_floats * target_sum
.Пример: Учитывая значения с плавающей точкой 0.1, 0.2, 0.5
и целевую сумму 16, результат должен быть 2, 4, 10
.
К сожалению, цифры не так хороши в реальности, поэтому я хотел бы минимизировать ошибку по сравнению с реальным, идеальным результатом.
Например, если целью было 17,это должно быть 2, 4, 11
.Первый float конвертируется в 0.1 / 0.8 * 17 = 2.125
.Второе и третье соответственно 4.25
и 10.6
.Ясно, что 10,6 следует округлить.
Однако простого округления на границе 0,5 не всегда достаточно.Во-первых, существует патологический случай масштабирования входных данных 1, 1
для суммирования 3: одно из значений должно быть 2, а другое 1, поэтому есть два эквивалентных решения.
Во-вторых, может потребоваться округление по-разному: Учитывая 0.1, 0.1, 0.3
и цель 8, мы получаем 0.1 / 0.5 * 8 = 1.6 => 2
и 0.3 / 0.5 * 8 = 4.8 => 5
, суммируя до 2 + 2 + 5 = 9
вместо 8.
Что было бы хорошим решением для этого примера?Это приходит на ум:
С 1.6 - 1
и т. Д.мы видим, что первый имеет абсолютные ошибки 0.6, 0.6, 1.2
.Как правило, я бы хотел сложить их в квадрат, чтобы получить:
1, 1, 6
-> (1.6 - 1)^2 + (1.6 - 1)^2 + (4.8 - 6)^2 = 0.36 + 0.36 + 1.44 = 2.16
1, 2, 5
-> (1.6 - 1)^2 + (1.6 - 2)^2 + (4.8 - 5)^2 = 0.36 + 0.16 + 0.04 = 0.56
2, 2, 4
-> (1.6 - 2)^2 + (1.6 - 2)^2 + (4.8 - 4)^2 = 0.16 + 0.16 + 0.64 = 0.96
Соответственно, 1, 2, 5
(или 2, 1, 5
) должно быть предпочтительным.
Я реализовал приблизительный решатель, который масштабирует значения с учетом оставшихсяоставленный пробел (целевая сумма минус текущая сумма), которая в основном работает нормально.Вместо того, чтобы улучшать его, я считаю, что это общая проблема с хорошими существующими решениями.Однако я не смог его найти - можете ли вы указать мне?
Я работаю в C / C ++ / C # -подобных языках, но здесь меня интересует только общий алгоритм.