Имя: Пароль:
LIFE
 
OFF: Алгоритм распределения суммы
0 tenikov
 
05.08.11
11:54
Есть колонка с произвольными неотрицательными числами. Хотелось бы равномерно вычесть из всех значений колонки фиксированную сумму, начиная с минимального значения в колонке, чтобы результат в колонке не стал ниже нуля:

--
Сумма = 100

2
12
35
50
70
--

Т.е. сначала из всех значений в колонке вычесть 2, затем 10 (минимальное оставшееся = 12 - 2) и так далее, пока в сумме эти вычитания не станут равны 100.

Подскажите, какой алгоритм использовать?
1 Rie
 
05.08.11
11:56
(0) Непонятно. Почему бы не подсчитать сумму колонки (пусть она будет S) и не вычесть из каждого элемента S/N, где N - количество строк?
2 Попытка1С
 
05.08.11
11:59
Не понятно что сложного...
3 Попытка1С
 
05.08.11
11:59
Сортировать, перебрать, вычислить, накопить, прервать.
4 tenikov
 
05.08.11
12:12
(1) ну например потому, что тогда некоторые значения в колонке станут отрицательными.

(3) мнится мне, должен быть рекурсивный вызов. так?

ЗЫ я не слишком рублю в математике (экономическое образование). спрашиваю у форума, т.к. не уверен.
5 catena
 
05.08.11
12:20
А что надо в итоге-то? Какие значения из какой строке были вычтены? Или остатки?
6 catena
 
05.08.11
12:20
"ЗЫ я не слишком рублю в математике (экономическое образование)."
нде...
7 Rie
 
05.08.11
12:23
(4) Тогда в (0) получается, что можно вычесть только 2 - потому что когда на втором шаге будет вычитаться 10, то в первой строке значение станет отрицательным. А если 2 вычитается из первой строки, а из второй - 10 и т.д. - то какое уж тут "равномерно"?

Но есть подозрение, что ответ был в (3).
8 tenikov
 
05.08.11
13:13
(7) >> А если 2 вычитается из первой строки, а из второй - 10 и т.д. - то какое уж тут "равномерно"?

2 вычитается из всех значений строк в колонках, где значение колонки больше нуля.
10 потом вычитается из всех, кроме первой (так как в первой уже ноль).

так до тех пор, пока общая сумма, которую вычли (2*колво строк + 10*колво строк + ...), не станет равно 100.

непонятно объясняю :) но как то так.
9 tenikov
 
05.08.11
14:08
короче, вот так, вроде:

--

Процедура РаспределитьСуммы()
   
   НомСтр = 0;
   Пока СуммаРаспределения > 0 Цикл
       ОбработкаПрерыванияПользователя();
       
       Если НомСтр > ТЗ.Количество() - 1 тогда
           Прервать;
       КонецЕсли;
       
       Если ТЗ[НомСтр].Сумма > 0 Тогда
           CуммаМинимум = Мин(ТЗ[НомСтр].Сумма, СуммаРаспределения);
           
           Для А = НомСтр По ТЗ.Количество() - 1 Цикл
               Распределить = Мин(CуммаМинимум, СуммаРаспределения);
               
               СуммаРаспределения = СуммаРаспределения - Распределить;
               ТЗ[А].Сумма = ТЗ[А].Сумма - Распределить;
           КонецЦикла;
       КонецЕсли;
       
       НомСтр = НомСтр + 1;
   КонецЦикла;
   
   Если СуммаРаспределения > 0 Тогда
       РаспределитьСуммы();
   КонецЕсли;
   
КонецПроцедуры
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс