VBA: Генерация данных, которые имитируют определенные параметры (Avg, StdDev..etc) - PullRequest
0 голосов
/ 10 января 2011

Я изменил функцию массива VBA, данную мне здесь: Генерация нормализованных данных в Excel

Этот вопрос объяснит, что мне нужно.


ЗагрузитьExcel, который я использую, чтобы полностью понять:

http://www.mediafire.com/?smq5tl9poitdacc


Я использую следующие данные (Левая сторона - значения, которые я ввожу для данных, на которых будут основываться,справа отображаются результаты сгенерированных данных):

alt text

Как видите,% Diff очень хорош для Avg Click, но Click / Time отключается, когда естьВысокий День StdDev (День +/-).Разница при низком значении Day Stddev близка к 0.

Я думаю, это связано с тем, что var NoClickDaysPerClick_Running_Avg становится неточным, поскольку NoClickDays_Total (который используется косвенночтобы определить текущее значение avg) «угадывается» в начале, и его необходимо переоценивать при каждом щелчке, потому что высокий StdDev добавляет случайность, а исходное «предположение» становится все более и более неточным.

Я не уверен, еслиэто проблема, или, если я так могу ее решить.

Я просто ищу совет о том, как сделать то, что я хочу.Я не уверен, почему stdDev так далеко, но это не имеет большого значения.Я предпочел бы иметь более точный клик / время, чем что-либо еще, независимо от того, что такое Day StdDev.


вот функция в моем VBA:

Function ClickSpacer(Total_Days As Long, ClicksPerDay_Desired_Avg As Double, Clicks_Desired_Deviation As Double, Clicks_Min As Integer, Clicks_Max As Integer, TotalClicksOverTotalDays_Desired_Avg As Double, NoClickDays_Desired_Deviation As Double, NoClickDays_Min As Integer, NoClickDays_Max As Integer)


    Dim Day_Array() As Integer
    ReDim Day_Array(1 To Total_Days, 1 To 1)

    Dim NumDaysToGetClicks As Double
    Dim ClickOffset As Long

    Dim Clicks_Total As Long
    Dim Clicks_SoFar As Long
    Dim Clicks_Remaining As Long


    Dim NoClickDaysPerClick_Desired_Avg As Double





    ' Number of clicks that are needed to Achieved desired Avg of clicks over time
    Clicks_Total = Round(Total_Days * TotalClicksOverTotalDays_Desired_Avg, 0)

    ' Number of days in which the user has to click atleast once to achieve desired Avg. clicks per day
    NumDaysToGetClicks = Round(Clicks_Total / ClicksPerDay_Desired_Avg, 0)

    ' The number of non-click days in order fill out the total days
    NoClickDays_Total = Round(Total_Days - NumDaysToGetClicks, 0)





    ' The guessimated average of non-click days per click to fill out total non-click days
    ' This is never used, just used for comparsion of the running Avg
    NoClickDaysPerClick_Desired_Avg = NoClickDays_Total / NumDaysToGetClicks





    'This variable is here to achieved closer results to the desired StdDev.
    'a higher multiplyer will not limit the deviation but just give an average deviation
    'For example, if the Average was 3 with a +/- 2, then with a StdDevMulti of 1
    'ALL numbers will be 1 (3-2) through 5  (3+2) with an avg of 3 and stddev of 2, the numbers will NEVER exceed the StdDev.
    'With a StdDevMulti of 2, the numbers will be 0 through 6, but should still have an
    'Avg deviation of 2.
    StdDevMulti = 1

    NoClickDays_Desired_Deviation = NoClickDays_Desired_Deviation * StdDevMulti
    Clicks_Desired_Deviation = Clicks_Desired_Deviation * StdDevMulti


    'Set the obvious defaults
    ClickedDaysSoFar = 0
    Clicks_SoFar = 0
    NoClickDays_SoFar = 0

    'Give the ClickOffset a starting value
    ClickOffset = NoClickDaysPerClick_Desired_Avg

    Do

        'used to find the "running" average of days not clicked
        NoClickDays_Remaining = NoClickDays_Total - NoClickDays_SoFar

        'used to find the "running" average of clicks per day
        Clicks_Remaining = (Clicks_Total - Clicks_SoFar)

        'used in both "running" averages mentioned above and also will
        'mark the end of the while loop.
        RemainingClickedDays = (NumDaysToGetClicks - ClickedDaysSoFar)


        ' Find what the average num. click should be based on the remaining
        ' and then apply the deviation. Only accept a click below its max
        ' above its min.
        Do

            ' Generate a random number between -1 and 1
            SignChanger = Rnd() - Rnd()

            ' Apply the randomized StdDev
            Clicks_Deviation = Clicks_Desired_Deviation * SignChanger

            'Figure out the "running" average
            ClicksPerDay_Running_Avg = Clicks_Remaining / RemainingClickedDays

            'Figure out a click value and round to the nearest whole number
            Generated_Clicks = Round(ClicksPerDay_Running_Avg + Clicks_Deviation, 0)

        ' Make sure it meets the requirements, if not, try again
        Loop While Generated_Clicks < Clicks_Min Or Generated_Clicks > Clicks_Max


        ' Set the click value to the spaced-out array index
        Day_Array(ClickOffset, 1) = Generated_Clicks


         'Find a random space based upon the "running" avg. and desired deviation
         'Make sure it between the min and max required.
         Do
             ' Generate a random number between -1 and 1
            SignChanger = Rnd() - Rnd()

            ' Apply the randomized StdDev
            NoClickDays_Deviation = NoClickDays_Desired_Deviation * SignChanger


            'Figure out the "running" average
            NoClickDaysPerClick_Running_Avg = NoClickDays_Remaining / RemainingClickedDays

            'Figure out a space value and round to the nearest whole number
            Generated_NoClickDays = Round(NoClickDaysPerClick_Running_Avg + NoClickDays_Deviation, 0)

        ' Make sure it meets the requirements, if not, try again
        Loop While Generated_NoClickDays < NoClickDays_Min Or Generated_NoClickDays >= NoClickDays_Max



        'Define the array index based upon the spacing previously generated.
        ' Make sure to "add" upon the already known index. Add 1 because you
        'have to account for the index the click occupies
        ClickOffset = ClickOffset + Generated_NoClickDays + 1




        'These should be self-explaintory
        ClickedDaysSoFar = ClickedDaysSoFar + 1
        Clicks_SoFar = Clicks_SoFar + Generated_Clicks
        NoClickDays_SoFar = NoClickDays_SoFar + Generated_NoClickDays

    Loop While ClickOffset < Total_Days And RemainingClickedDays > 0



    'Set the array equal to the clicks so that it returns the array as
    'we want. Ideally this will be just replace Total_Days fields under
    'the base, so not to require a array-function. Neither of these work:
    'ClickSpacer = Range("P1:P" & UBound(Day_Array) + 1).Value
    'Range("P1:P" & UBound(Day_Array) + 1) = Application.Transpose(Day_Array)


    ClickSpacer = Day_Array



End Function

1 Ответ

0 голосов
/ 29 января 2011

Я думаю, ваше предположение верно.«Проблема» в приведенном выше коде состоит в том, что он использует StdDev в качестве основы для генерации случайных чисел, поэтому стандартное отклонение будет иметь тенденцию быть точным, а среднее будет менее точным.

Если вы хотите большеточность со средним значением и меньшая со стандартным отклонением, тогда вам придется «перевернуть» то, как генерируются числа: им нужно будет сосредоточиться вокруг желаемого среднего значения и использовать желаемое стандартное отклонение в качестве ориентира, а не наоборот.около.

У меня есть идея о том, как это можно сделать, но это займет больше концентрации, чем я могу применить на работе, поэтому мне придется вернуться и отредактировать это позже.Я посмотрю, что я могу сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...