Прогнозировать необходимое количество итераций-взвешенное среднее число итераций
Простите, но я мог бы найти название получше. Пожалуйста, посмотрите на эту супер-простую программу Python:
x = start = 1.0
target = 0.1
coeff = 0.999
for c in range(100000):
print('{:5d} {:f}'.format(c, x))
if abs(target - x) < abs((x - start) * 0.01):
break
x = x * coeff + target * (1 - coeff)
Краткое пояснение: эта программа движется x к target, вычисляя итеративно средневзвешенное значение x и target с coeff в качестве веса. Он останавливается, когда x достигает 1% от начальной разницы.
Число итераций остается неизменным независимо от начального значения x и target.
Как я могу установить coeff, чтобы предсказать, сколько повторения будут иметь место?
Большое спасибо.
2 ответов:
Давайте сделаем это функцией,
f.
f(0)является начальным значением (start, в данном случае1.0).
f(x) = f(x - 1) * c + T * (1 - c).(таким образом,
f(1)- следующее значение x,f(2)- следующее после этого и т. д. Мы хотим найти значениеxгде|T - f(x)| < 0.01 * |f(0) - f(x)|)Итак, давайте перепишем
f(x), Чтобы быть линейными:f(x) = f(x - 1) * c + T * (1 - c) = (f(x - 2) * c + T * (1 - c)) * c + T * (1 - c) = (f(x - 2) * c ** 2 + T * c * (1 - c)) + T * (1 - c) = ((f(x - 3) * c + T * (1 - c)) * c ** 2 + T * c * (1 - c)) + T * (1 - c) = f(x - 3) * c ** 3 + T * c ** 2 * (1 - c) + T * c * (1 - c) + T * (1 - c) = f(0) * c ** x + T * c ** (x - 1) * (1 - c) + T * c ** (x - 2) * (1 - c) + ... + T * c * (1 - c) + T * (1 - c) = f(0) * c ** x + (T * (1 - c)) [(sum r = 0 to x - 1) (c ** r)] # Summation of a geometric series = f(0) * c ** x + (T * (1 - c)) ((1 - c ** x) / (1 - c)) = f(0) * c ** x + T (1 - c ** x)Таким образом, N-е значение x будет
start * c ** n + target * (1 - c ** n).Мы хотим:
|T - f(x)| < 0.01 * |f(0) - f(x)| |T - f(0) * c ** x - T (1 - c ** x)| < 0.01 * |f(0) - f(0) * c ** x - T (1 - c ** x)| |(c ** x) * T - (c ** x) f(0)| < 0.01 * |(1 - c ** x) * f(0) - (1 - c ** x) * T| (c ** x) * |T - f(0)| < 0.01 * (1 - c ** x) * |T - f(0)| c ** x < 0.01 * (1 - c ** x) c ** x < 0.01 - 0.01 * c ** x 1.01 * c ** x < 0.01 c ** x < 1 / 101 x < log (1 / 101) / log c(я как-то закончил с
В конце концов, она независима отx <, когда это должно бытьx >, но это дает правильный ответ. С помощьюc = 0.999,x > 4612.8, и он заканчивается на шаге4613).startиtarget.Также, для общей процентной разницы
p,Таким образом, для коэффициентаc ** x > p * (1 - c ** x) c ** x > p - p c ** x (1 + p) c ** x > p c ** x > p / (1 + p) x > log (p / (1 + p)) / log ccбудутlog (1 / 101) / log cшаги.Если у вас есть нужное количество шагов, назовите его
I, у вас естьI = log_c(1 / 101) c ** I = 1 / 101 c = (1 / 101) ** (1 / I)Поэтому
cдолжно быть установлено вI- й корень1 / 101.
Ваш код уменьшает расстояние между x и целью на коэффициент
coeffпри каждом выполнении цикла. Таким образом, еслиstartбольшеtarget, то получим формулуtarget - x = (x - start) * coeff ** cГде
c- количество выполненных петель.Ваш конечный критерий (опять же, если
startбольше, чемtarget),x - target < (start - x) * 0.01Решая для
xалгеброй получаемx > (target + 0.01 * s) / (1 + 0.01)Подставляя это в наше первое выражение и упрощая бит, мы получаем как
start, так иtargetотбросьте неравенство-теперь вы видите, почему эти значения не имели значения-и мы получим0.01 / (1 + 0.01) < coeff ** cРешая для
cполучаемc > log(0.01 / (1 + 0.01), coeff)Таким образом, окончательный ответ для числа циклов равен
ceil(log(0.01 / (1 + 0.01), coeff))Или же, если вам не нравятся логарифмы с произвольным основанием,
Вы могли бы заменить этот первый логарифм в последнем выражении его результатом, но я оставил его таким, чтобы посмотреть, какой другой результат вы получите, если измените константу в конце критерий вдали отceil(log(0.01 / (1 + 0.01)) / log(coeff))0.01.Результатом этого выражения в вашем конкретном случае является
4613Что верно. Обратите внимание, что обе функции
ceilиlogнаходятся в блокеmathPython, поэтому не забудьте импортировать эти функции перед выполнением этого вычисления. Также обратите внимание, что вычисления Python с плавающей точкой не точны, поэтому ваше фактическое число циклов может отличаться от этого на единицу, если вы измените значенияcoeffили0.01.
Comments