Дан ряд F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k В нем X и K известны начальное приближение F0=1, Условие остановки abs(F(n-1)-F(n))<0.0001 Надо решить рекурсией, циклом я решил. Так для сведения, это ряд для нахождения корня из числа.
Вот что я накидал,но чет не работает, помогите пожалуйста
Sub Test() x = 4 k = 2 Cells(10, 10) = F(n) End Sub Function F(n As Integer) As Double If n = 0 Then F = 1 Else F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k End If End Function
Дан ряд F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k В нем X и K известны начальное приближение F0=1, Условие остановки abs(F(n-1)-F(n))<0.0001 Надо решить рекурсией, циклом я решил. Так для сведения, это ряд для нахождения корня из числа.
Вот что я накидал,но чет не работает, помогите пожалуйста
Sub Test() x = 4 k = 2 Cells(10, 10) = F(n) End Sub Function F(n As Integer) As Double If n = 0 Then F = 1 Else F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k End If End FunctionАлександр
Sub Test()
x = 4
k = 2
Cells(10, 10) = F(n) EndSub Function F(n AsInteger) AsDouble If n = 0Then
F = 1 Else
F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k EndIf EndFunction
Если бы Вы не пренебрегали рекомендациями учителей-основателей о желательности (по крайней мере на первых порах обучения) задания в модулях декларации Option Explicit, обязывающей объявлять переменные, то сразу бы поняли, что функция у Вас просто не корректно вызывается из процедуры Test. Ведь в Sub Test аргумент n у Вас не определён, поэтому, вызываемая в строке Cells(10, 10) = F(n) функция считает его по умолчанию n=0 (т.к. ей указано, что аргумент n As Integer ). Ну и , естественно, сразу же принимает значение 1 и никакой рекурсии не происходит. Да и параметры х и k Вы функции не передаёте, поэтому они тоже считаются по умолчанию =0 со всеми вытекающими последствиями
Пользуйтесь тэгами оформления кодов процедур
Sub Test()
x = 4
k = 2
Cells(10, 10) = F(n) EndSub Function F(n AsInteger) AsDouble If n = 0Then
F = 1 Else
F = F(n - 1) + (x / ((F(n - 1)) ^ (k - 1)) - F(n - 1)) / k EndIf EndFunction
Если бы Вы не пренебрегали рекомендациями учителей-основателей о желательности (по крайней мере на первых порах обучения) задания в модулях декларации Option Explicit, обязывающей объявлять переменные, то сразу бы поняли, что функция у Вас просто не корректно вызывается из процедуры Test. Ведь в Sub Test аргумент n у Вас не определён, поэтому, вызываемая в строке Cells(10, 10) = F(n) функция считает его по умолчанию n=0 (т.к. ей указано, что аргумент n As Integer ). Ну и , естественно, сразу же принимает значение 1 и никакой рекурсии не происходит. Да и параметры х и k Вы функции не передаёте, поэтому они тоже считаются по умолчанию =0 со всеми вытекающими последствиямиAlex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Вторник, 20.05.2014, 22:49
Sub Test() Dim n AsInteger, x AsInteger, k AsInteger
x = 4
k = 2
n = 3 'Cells(10, 10) = F(n, x, k) Debug.Print F(n, x, k) EndSub Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble If n = 0Then
F = 1 Else
F = F(n - 1, x, k) + (x / ((F(n - 1, x, k)) ^ (k - 1)) - F(n - 1, x, k)) / k EndIf EndFunction
Хотя я рекурсии и не очень люблю.
Вот так попробуйте:
Sub Test() Dim n AsInteger, x AsInteger, k AsInteger
x = 4
k = 2
n = 3 'Cells(10, 10) = F(n, x, k) Debug.Print F(n, x, k) EndSub Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble If n = 0Then
F = 1 Else
F = F(n - 1, x, k) + (x / ((F(n - 1, x, k)) ^ (k - 1)) - F(n - 1, x, k)) / k EndIf EndFunction
Проверил в пошаговом режиме. Вот так меньше циклов, т.к. в случае Else проходит одно рекурсивное вычисление для вычисления F(n-1), а не три, дающих один и тот же результат.
Sub Test() Dim n AsInteger, x AsInteger, k AsInteger
x = 4
k = 2
n = 3 'Cells(10, 10) = F(n, x, k) Debug.Print F(n, x, k) EndSub Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble Dim Fn If n = 0Then
F = 1 Else
Fn = F(n - 1, x, k)
F = Fn + (x / ((Fn) ^ (k - 1)) - Fn) / k EndIf EndFunction
Проверил в пошаговом режиме. Вот так меньше циклов, т.к. в случае Else проходит одно рекурсивное вычисление для вычисления F(n-1), а не три, дающих один и тот же результат.
Sub Test() Dim n AsInteger, x AsInteger, k AsInteger
x = 4
k = 2
n = 3 'Cells(10, 10) = F(n, x, k) Debug.Print F(n, x, k) EndSub Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble Dim Fn If n = 0Then
F = 1 Else
Fn = F(n - 1, x, k)
F = Fn + (x / ((Fn) ^ (k - 1)) - Fn) / k EndIf EndFunction
В коде не реализовано n не должно задаваться, расчеты должны сами останавливаться (не люблю я рекурсии, нужно подумать, как это реализовать)
Если запустить предложенный код при n=20, то расчетов можно не дождаться для ускорения расчетов функцию для F(n-1) лучше вычислять один раз, а не три
Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble Dim F1 AsDouble If n = 0Then
F = 1 Else
F1 = F(n - 1, x, k)
F = F1 + (x / (F1 ^ (k - 1)) - F1) / k EndIf EndFunction
В коде не реализовано n не должно задаваться, расчеты должны сами останавливаться (не люблю я рекурсии, нужно подумать, как это реализовать)
Если запустить предложенный код при n=20, то расчетов можно не дождаться для ускорения расчетов функцию для F(n-1) лучше вычислять один раз, а не три
Function F(n AsInteger, x AsInteger, k AsInteger) AsDouble Dim F1 AsDouble If n = 0Then
F = 1 Else
F1 = F(n - 1, x, k)
F = F1 + (x / (F1 ^ (k - 1)) - F1) / k EndIf EndFunction
при n=20, то расчетов можно не дождаться для ускорения расчетов функцию для F(n-1) лучше вычислять один раз, а не три
Миш, я раньше поправил свой первый код
А в условие задачи я даже и не смотрел, честно говоря. Думал, что в своём коде топик-стартер все условия учёл, только не верно вызывал процедуру. Думать как сделать выход лень. Опять мы с тобой совпали во мнениях:
при n=20, то расчетов можно не дождаться для ускорения расчетов функцию для F(n-1) лучше вычислять один раз, а не три
Миш, я раньше поправил свой первый код
А в условие задачи я даже и не смотрел, честно говоря. Думал, что в своём коде топик-стартер все условия учёл, только не верно вызывал процедуру. Думать как сделать выход лень. Опять мы с тобой совпали во мнениях:
Sub test2() Dim x#, k#, eps#, f#, f0#
x = 1225
k = 2
eps = 0.0001
f = 1 Do
f0 = f
f = f0 + (x / f0 ^ (k - 1) - f0) / k LoopUntilAbs(f - f0) < eps Debug.Print f EndSub
а вот так можно сделать на рекурсиях
Sub test3() Debug.Print f(1, 1225, 2, 0.001) EndSub
Function f#(f0#, x#, k#, eps#) Dim fn#
fn = f0 + (x / f0 ^ (k - 1) - f0) / k IfAbs(fn - f0) < eps Then f = fn Else f = f(fn, x, k, eps) EndFunction
когда писал, не видел поправок. Наверно я слишком долго формулирую мысли
циклами задача решается так:
Sub test2() Dim x#, k#, eps#, f#, f0#
x = 1225
k = 2
eps = 0.0001
f = 1 Do
f0 = f
f = f0 + (x / f0 ^ (k - 1) - f0) / k LoopUntilAbs(f - f0) < eps Debug.Print f EndSub
а вот так можно сделать на рекурсиях
Sub test3() Debug.Print f(1, 1225, 2, 0.001) EndSub
Function f#(f0#, x#, k#, eps#) Dim fn#
fn = f0 + (x / f0 ^ (k - 1) - f0) / k IfAbs(fn - f0) < eps Then f = fn Else f = f(fn, x, k, eps) EndFunction
когда писал, не видел поправок. Наверно я слишком долго формулирую мысли
Михаил, я же слово "пишу" в прошедшем времени не просто так пишу с заглавной А - "писАл" Дабы не было разночтений и кривотолков. А то иногда очень двусмысленно звучит и надо мной как-то давно на одном из форумов поглумились
когда писал, не видел поправок. Наверно я слишком долго формулирую мысли
Михаил, я же слово "пишу" в прошедшем времени не просто так пишу с заглавной А - "писАл" Дабы не было разночтений и кривотолков. А то иногда очень двусмысленно звучит и надо мной как-то давно на одном из форумов поглумились [/offtop]Alex_ST