генерация случайного числа с нормальным распределением в VBA - ошибка времени выполнения "1004" - PullRequest
0 голосов
/ 26 января 2019

У меня проблема с генерацией случайных чисел с нормальным распределением в VBA.Я работаю над NSGAII.Я использую «Application.WorksheetFunction.Norm_Inv (Rnd, Mean, Deviation)» для генерации случайных чисел с нормальным распределением.Но у меня возникает эта ошибка:

Ошибка времени выполнения '1004': невозможно получить свойство Norm_Inv класса функций листа

Как я могу исправить эту ошибку?

Я уже использовал этот код в другом простом макросе, и он работает.Но при использовании этого кода в коде NSGAII возникает ошибка!(Большое количество переменных (double, long, Boolean и т. Д.) И двумерные массивы определены и используются в коде NSGAII, и он состоит из циклов do while, for и т. Д.)

Я использовалточка останова в строке «Функция GenerateNormRand () As Double».когда я ломаюсь и продолжаю (запускаю код шаг за шагом), ошибки нет!Но когда нет, возникает ошибка.

Option Explicit
Function Mutation () As Variant
    .
    .
    .
    Dim RandomNumber As Double
    RandomNumber = GenerateNormRand ()
    .
    .
    .
End Function

Function GenerateNormRand () as double
    Dim myrand As Double
    randomize
    myrand = Application.WorksheetFunction.Norm_Inv(Rnd, 0, 5)
    GenerateNormRand = myrand
End Function

Даже с явным объявлением Double для каждой входной и выходной переменной строка GenerateNormRand = Application.WorksheetFunction.Norm_Inv ... вызывает ошибку времени выполнения 1004:

Sub TestThisFunction()
    MsgBox GenerateNormRand
End Sub

Function GenerateNormRand() As Double
    Randomize
    GenerateNormRand = Application.WorksheetFunction.Norm_Inv( _
        CDbl(Rnd), CDbl(0), CDbl(5))
End Function

1 Ответ

0 голосов
/ 27 января 2019

Ваше описание проблемы выглядит загадочным, но если вы хотите обойти функцию листа, вы можете использовать преобразование Бокса-Мюллера для генерации собственных нормальных случайных величин в чистом VBA:

Function RandNorm(Optional mean As Double = 0, Optional sd As Double = 1) As Double
    Dim r1 As Double, r2 As Double, s As Double
    r1 = Rnd()
    If r1 = 0 Then r1 = Rnd() 'no danger of two zeros in a row in rnd()
    r2 = Rnd()
    s = Sqr(-2 * Log(r1)) * Cos(6.283185307 * r2) '6.28 etc. is 2*pi
    RandNorm = mean + sd * s
End Function
...