Всем привет.
Мне нужно подсчитать количество итераций для X, который каждую итерацию уменьшается на дельту от самого себя, до тех пор пока не выполнится определенное условие.
Допустим X=10, дельта=0.5 от X, условие X<1, тогда узнать количество итераций можно таким способом:
Цикл { кол-во_итераций++; X = X - X * 0.5; Если X < 1 то выход из цикла; }
В итоге получаю 4 итерации, где X принимает следующие значения: 10-->5-->2.5-->1.25-->0.625
Вопрос: как можно узнать дельту от X, если известны:
1. количество итераций = 4
2. начальный X0 = 0.625
3. конечный X1 = 10
Я составил уравнение:
x1 * дельта + x1 * дельта^2 + x1 * дельта^3 +x1 * дельта^4 = x1 - x0
Но как отсюда вытащить дельту не знаю, также непонятно, как в уравнении отразить количество итераций в виде переменной.
Возможно существует какой-нибудь простой способ, но я даже не знаю, как правильно сформулировать запрос к гуглу.
Andariil
> Мне нужно подсчитать количество итераций для X
Andariil
> как можно узнать дельту от X
Так количество итераций или дельту?
количество_итераций > ln(X)/ln(1/(1-дельта)) ln(10)/ln(1/(1-0.5)) = 3.32 количество_итераций = 4
вывод:
r = x - x * d =>
r = x * (1 - d ) =>
каждая итерация добавляет умножение на (1-d), следовательно:
r = x * (1 - d ) ^ n
действительно 10 * 0,5 ^ 4 равно 0.625
r/x = (1-d) ^ n
логарифмы уже вспоминать лень.
хотя чуток продолжу из любопытства
дельта легко:
(1-d) = root{n}(r/x)
d = 1 - root{n}(r/x)
n уже через логарифмы:
n = log {1-d} (r/x)
в программировании обычно натуральный логарифм только доступен, поэтому
n = ln(r/x) / ln( 1- d)
entryway
а куда делся конечный икс из формулы?
=A=L=X=
entryway
Большое спасибо, то что нужно!
=A=L=X=
> а куда делся конечный икс из формулы?
Я по первому предложению понял, что у него есть X=10 и он хочет узнать сколько раз его надо домножить на (1-delta) чтобы в результате получилось число меньше чем 1.
Ответ: N > ln(X)/ln(1/(1-delta))
Ну или: N = ceil(ln(X)/ln(1/(1-delta)))
Изначально я забыл отнять дельту от единицы. Подправил.
Andariil
в логарифмах я где то накосячил, не срастается...
=A=L=X=
> в логарифмах я где то накосячил, не срастается...
Я сделал так:
var count:int=Math.log(x0/x1)/Math.log(1-delta)+1;
var delta:Number=1-Math.pow(x0/x1,1/count);
Проверил - работает. Формула для дельты и без логарифмов простая.
Еще раз спасибо!
а, всё правильно, просто на маленьких числах может вылезти в область отрицательных, надо просто отбросить знак и округлить до ближайшего целого.
P.S.
А, освежил память - отрицательный count будет получаться если числа в ряду уменьшались, положительный - если увеличивались. Но сама абсолютная величина равна числу итераций, так что прогнав через abs заметаем эту ненужную информацию под ковёр.
Andariil
Вообще если у нас есть какая-то функция типа такой:
t_out func(const t_inp&value);
то для неё можно определить обратную функциювот примерно так:
t_inp arcfunc(const t_out&value) { for( auto i=-t_out::inf;i<=+t_out::inf;i++) { if( func( i)==value)return i; } assert( false); return *( t_inp)nullptr; }
А потом если она будет тормозить, то попробовать её оптимизировать :D
А если не будет тормозить, то тогда можно просто подажать когда компияторы научатся сами это делать.
Задача - это по сути элементарная геометрическая прогрессия.
bn=b1*q^n, где:
b1 - 1-ый член прогрессии (авторский X0)
bn - последний известный член прогрессии (авторский X1)
n - номер bn (авторское количество итераций)
q - "разность"
следуя из этой формулы легко найти q, если известны b1, bn и n:
q = root{n}(bn/b1)
q = exp(log(bn/b1)/n)
или найти n, если известны b1, bn и q:
n = log{q}(bn/b1)
n = log(bn/b1)/log(q)
P.S. я так понимаю либо автор перепутал X0 и X1 местами, либо он вместо q берет 1/q, в любом случае приведенные формулы дегко модифицировать под оба случая.
Тема в архиве.