Распределение уменьшающегося количества за X дней

Я пытаюсь построить график распределения доставки известного количества в убывающей манере в течение X дней. Мне нужна помощь с формулой, которую я могу реализовать в php.

Константы будут равны 10 000 единиц, а начальное значение — 300 % от усредненного распределения (извините за плохие термины).

Например:

10 000 единиц будут распределены в течение 10 дней. В первый день доставка будет на 300% выше, чем обычно, то есть 3000. Число будет падать в течение следующих 9 дней, пока все не будут доставлены.

Я могу подделать приведенный выше пример с помощью Excel, вычислив коэффициент, умножающий каждую доставку, чтобы уменьшить ее (в этом примере 0,71).

Я буду реализовывать это в php. Дни могут варьироваться от 3 до 365 дней.

Поэтому в идеале решение позволило бы мне сделать что-то из следующего:

$units = array();
$startValue = (10000 / $daysToDeliver) * 3;
for ($x= 0, $x < $daysToDeliver, $x++) {
   //add the next deliver quantity onto the array
   $units[] = awesomefunction($lastDeliverAmount, $daysLeftToDeliver);  // guessing here
}

Я знаю, что слишком упрощаю входные данные для функции, просто пытаюсь дать общее представление.

Спасибо за ваше время и внимание!


person Ryan    schedule 18.02.2014    source источник


Ответы (2)


Как упоминает Мэнни Рамирес, это похоже на экспоненциальную функцию затухания; за исключением того, что он не непрерывный, а дискретный. Вы в основном хотите производить:

seq(3a/n*(1-r)^(i-1)) for i from 1 to n

где в вашем случае

a = 10000
n = 10
r = necessary value such that sum(seq(...)) == a == 10000

Задача состоит в том, чтобы найти р. Я использовал a = ∑3a/n*(1-r)^(i-1) for i from 1 to n. Выполняя некоторые алгебраические манипуляции, я упростил это до:

3(1-r)^n+r*n-3=0

Но, честно говоря, без системы компьютерной алгебры нет простого способа решить эту проблему. Честно говоря, как бы мне ни нравился PHP, он отстой в таких вещах. В Python может быть модуль, который сделает это за вас. Это сказало...

  • Если у вас есть надежный доступ к Excel, вы можете использовать средство решения уравнений в сочетании с API Excel (http://office.microsoft.com/en-us/excel-help/define-and-solve-a-problem-by-using-solver-HP010072691.aspx). Я использовал это и получил скорость, которую вы сделали (точнее, 0,290271556501). Немного увеличьте допуск, если это не удается решить. Также установите ограничение, что 0 ‹ r ‹ 1, иначе вы можете получить несколько ответов (или просто неверный, если он перестанет пытаться после нахождения одного).
  • Вы можете попробовать использовать API онлайн-решателя, такого как Wolfram Alpha(http://products.wolframalpha.com/api/).
  • Здесь есть еще один пост stackoverflow о компьютерной алгебре в PHP: Как вы можете решать уравнения в PHP ?
  • Вы можете написать свое собственное приложение компьютерной алгебры для PHP (очевидно, я не рекомендую это).

После того, как вы использовали один из этих методов (или другой) для поиска r, вам нужно построить массив:

function getUnits ($total, $days, $rate) {
  $start = $total * 3 / $days;
  $units = array();
  for ($i = 1; $i <= $days; $i++) {
    $units[] = $start * pow((1 - $rate), $i - 1);
  }
  return $units;
}

//try with the numbers we have here
$units = getUnits(10000, 10, 0.290271556501);
print_r($units);
echo array_sum($units);

Это дает

>> Array ( [0] => 3000 [1] => 2129.185330497 [2] => 1511.1433905345 [3] => 1072.5014464679 [4] => 761.18478225207 [5] => 540.23449072289 [6] => 383.41978422523 [7] => 272.1239266649 [8] => 193.13409091071 [9] => 137.07275772865 )
>> 10000.000000004
person ChicagoRedSox    schedule 19.02.2014
comment
Большое спасибо за ваш подробный ответ. Похоже, что нет простого способа сделать это только с помощью PHP. - person Ryan; 19.02.2014

Вы имеете дело с проблемой роста и распада. Распад задается следующей формулой: y=a(1-r)^x. a — начальная сумма, y — сумма, отправляемая каждый день, и x — количество дней, которое в вашем случае равно 10- 1, так как вы заставляете сумму 1-го дня быть a/x*3. Затем достаточно просто рассчитать скорость r и построить простую петлю.

person Manny Ramirez    schedule 19.02.2014
comment
Спасибо за отзыв Мэнни. Собираюсь попробовать php и посмотреть, смогу ли я заставить его работать. Один быстрый вопрос, и я мог бы неправильно понять ваше решение: как мне рассчитать скорость (R) в то же время, когда я рассчитываю количество, отправляемое каждый день (Y)? - person Ryan; 19.02.2014