Разбиение по «методу Пугаева» или «разность округлённых значений»
Разработчикам часто приходиться сталкиваться с задачей, когда нужно некую сумму S, распределить между строками, пропорционально некому значению Q в этой строке и записать в F.
Как она решается?
Для каждой строки F = ROUND( Q * S /SUM(Q) ) ; где S /SUM(Q) – цена одной штуки.
Проблема в том, что при округлении, теряются или появляются копейки
Решим простенькую задачу, округлять будем до целого.
У Маши было пять яблок за шесть рублей. Дима взял одно яблоко, Саша и Коля по два. Кто сколько рублей должен Маше?
Начнём считать рубли по формуле.
Дима: ROUND( 1 * 6/5 ) = 1
Саша: ROUND( 2 * 6/5 ) = 2
Коля: ROUND( 2 * 6/5 ) = 2
Цена одного яблока ROUND(6/5) = 1 рубль, получается Маша возьмёт с ребят пять рублей. Это несправедливо.
Для решения этой задачи нам недостаточно знать кто сколько взял, нужно знать в каком порядке они их взяли. Дима взял первое, Саша – второе и третье, Коля – четвертое и пятое. Это ключевой момент в решении!
Таким образом, два яблока, которые взял Саша – непростые, они имеют свое место в общей куче.
В чём заключается «метод Пугаева»? Нужно оценивать не яблоко, а кучку яблок с учётом его места в общей куче. Дима взял с нулевого, по первое яблоко, Саша – с первого, по третье, Коля – с третьего, по пятое.
Кучка с N по M, стоит как разность: M*price –N*price
Выведем формулу: F = ROUND( M * S /SUM(Q) ) — ROUND(N * S /SUM(Q) )
Посчитаем:
Дима: ROUND( 1 * 6/5 ) — ROUND(0 * 6/5 ) = 1 – 0 = 1
Саша: ROUND( 3 * 6/5 ) — ROUND(1 * 6/5 ) = 4 – 1 = 3
Коля: ROUND( 5 * 6/5 ) — ROUND(3 * 6/5 ) = 6 – 4 = 2
Я продемонстрировал принцип, который поможет программистам и не только, в решении задач. Самое главное – это увидеть, что число не просто число, а какая-то часть от большого числа, имеющая свое место внутри этого большого числа. Этот метод помог мне правильно посчитать НДС для многострочного документа, каждая строка имеет свое место в общем документе.

Автор: Дмитрий Пугаев
Количество статей, опубликованных автором: 3. Дополнительная информация об авторе появится вскоре.
Sie-haben einen fantastischen Blog Dank. Loren Hermon Ryle