Страницы: 1
RSS
Посмогите создать список случайных дат и времени по алгоритму
 
Требуется создать столбец со временем по следующему алгоритму:

1.На каждый день должно быть создано от 20 до 25 отрезков времени
2.Каждый отрезок времени может быть в диапазоне от 15 минут до 50 минут от предыдущего
3. 80-90% времени должны быть в диапазоне от 8 утра до 1 ночи (в ночное время отрезков меньше)

Вроде такого (можно с датами, можно без, главное время)

0:21
0:58
4:30
7:11
8:22
9:51
10:26
11:17
11:48
14:31
15:04
17:22
18:15
18:38
19:29
20:01
20:27
20:48
21:19
21:34
23:16
23:59

Как решить такую задачу?
Спасибо
 
Цитата
Seller написал:
0:21   0:58   4:30   7:11   8:22   9:51
А где тут выполнение условия
Цитата
Seller написал:
Каждый отрезок времени может быть в диапазоне от 15 минут до 50 минут от предыдущего
И что такое вообще "отрезки" времени из Вашего объяснения?
 
Сгенерируйте случайных 20 значений формулой:
Код
=ОКРУГЛТ(НОРМ.ОБР(СЛЧИС();0,7;0,11);1/24/6)
Можете поварьировать среднее значение и стандартное отклонение по своему усмотрению.
В соседних столбцах выведите эти значения по возрастанию.
Добавьте ограничения по минимальной и максимальной разнице.
 
surkenny, ну про отрезки мне кажется все понятно, хотя и ТС явно путает отрезок времени и начало этого отрезка, а вот с выполнением условий и правда в примере не все хорошо.
0:58
4:30
7:11
тут явно более 50 минут.
По вопросам из тем форума, личку не читаю.
 
Цитата
написал:
Можете поварьировать среднее значение и стандартное отклонение по своему усмотрению.
Спасибо.
не осилить мне.
Ставлю разные параметры отличные от ваших, начинает округлять до 10 минут.

=ОКРУГЛТ(НОРМ.ОБР(СЛЧИС();0,9;0,27);1/24/6)
 
БМВ, так я уже начал думать, что, может, 2n+1 элементы - начало, а 2n - конец - вот и отрезок :) Хотя тогда нечетное число (25) элементов не подходит под эту логику и все равно промежутки в 15-50 минут не укладываются. Поэтому и уточняю.
Ну раз ТС не отвечает на вопросы, то и нет смысла реализовывать :)

Цитата
Seller написал:
начинает округлять до 10 минут
А не пробовали 1/24/6 на 1/24/60 поменять?

Ну и 25 отрезками со случайной разницей между ними 15-50 мин в среднем можно "покрыть" 16 часов из 24 (максимум - 20 с разницей в 50 минут).
Изменено: surkenny - 27.11.2023 10:13:32
 
Цитата
написал:
Ну и 25 отрезками со случайной разницей между ними 15-50 мин в среднем можно "покрыть" 16 часов из 24 (максимум - 20 с разницей в 50 минут).
Согласен, диапазон значений значит увеличу до адекватного.
Или можно сделать минимальное значение не менее 15 минут, а верхнее - рандомно.
Изменено: Seller - 27.11.2023 10:29:40
 
Seller, я вообще не формулист :)
Но у меня ощущение, что формула МатросНаЗебре вообще не будет учитывать промежутки между временем. Можно получить и менее 15 минут и более 50 между ближайшим временем после сортировки.
Я уверен, что МатросНаЗебре Вам напишет нужную формулу, или БМВ предложит :) Но только если норм ТЗ будет.
 
Цитата
написал:
Но у меня ощущение, что формула  МатросНаЗебре  вообще не будет учитывать промежутки между временем. Можно получить и менее 15 минут и более 50 между ближайшим временем после сортировки.
Закреплю Ваше предположение, именно так она и работает ) Для ограничения продолжительность я предлагал использовать вспомогательные столбцы.
Цитата

В соседних столбцах выведите эти значения по возрастанию.
Добавьте ограничения по минимальной и максимальной разнице.
 
Спасибо, что откликнулись  :D
Попробую пересобрать ТЗ.

Нужно.

1. 30 рандомных позиций времени от 00.00 до 23.59 в порядке возрастания
2. Минимальный интервал - 15 минут
3. 25-27 значения находятся в интервалах 00.00-00.01 и 07.00-23.59
4. 5-3 значений находятся в интервале 00.01-07.00
Изменено: Seller - 27.11.2023 19:31:24
 
Код
Option Explicit

Sub RndA1()
    RndRange Range("A1")
End Sub

Private Sub RndRange(rr As Range)
    Dim Application_Calculation As Long
    Application_Calculation = Application.Calculation
    Application.Calculation = xlCalculationManual
    
    Dim arr As Variant
    arr = GetRndArr()
    
    Set rr = rr.Cells(1, 1).Resize(UBound(arr, 1), UBound(arr, 2))
    
    rr.Value = arr
    arr = SortArray(rr)
    Less15 arr, 15 / 24 / 60
    
    rr.Value = arr
    arr = SortArray(rr)
    
    MorningMax arr, 5, 7 / 24, rr
    MorningMin arr, 3, 7 / 24, rr, 15 / 24 / 60
    DayFill arr, 7 / 24, rr, 15 / 24 / 60
    
    
    rr.Value = arr
    arr = SortArray(rr)
        
    Application.Calculation = Application_Calculation
End Sub

Private Sub DayFill(arr As Variant, dtMorning As Double, rr As Range, deltat As Double)
    Dim ym As Long
    Dim ye As Long
    Dim y1 As Long
    Dim d1 As Double
    Dim d2 As Double
    Do
        If Not IsEmpty(arr(UBound(arr, 1), 1)) Then Exit Do
        
        ym = MorningMaxIndex(arr, dtMorning)
        For y1 = ym + 1 To UBound(arr, 1) - 1
            If arr(y1 + 1, 1) - arr(y1, 1) > 2 * deltat Then
                ye = UBound(arr, 1)
                d1 = arr(y1, 1) + deltat
                If d1 > arr(y1 + 1, 1) Then d1 = arr(y1 + 1, 1)
                d2 = arr(y1 + 1, 1) - deltat
                If d2 <= d1 Then d2 = d1
                arr(ye, 1) = Rnd() * (d2 - d1) + d1
                Exit For
            End If
        Next
        
        rr.Value = arr
        arr = SortArray(rr)
        DoEvents
    Loop
End Sub


Private Sub MorningMin(arr As Variant, nMin As Long, dtMorning As Double, rr As Range, deltat As Double)
    Dim ym As Long
    Dim ye As Long
    Dim y1 As Long
    Dim d1 As Double
    Dim d2 As Double
    Do
        ym = MorningMaxIndex(arr, dtMorning)
        If ym >= nMin Then Exit Do
        If ym = 0 Then
            ye = 1
            arr(ye, 1) = Rnd() * dtMorning
        Else
            For y1 = 1 To ym
                If arr(y1 + 1, 1) - arr(y1, 1) > 2 * deltat Then
                    ye = UBound(arr, 1)
                    d1 = arr(y1, 1) + deltat
                    If d1 > arr(y1 + 1, 1) Then d1 = arr(y1 + 1, 1)
                    d2 = arr(y1 + 1, 1) - deltat
                    If d2 <= d1 Then d2 = d1
                    
                    arr(ye, 1) = Rnd() * (d2 - d1) + d1
                    
                    Exit For
                End If
            Next
        End If
        
        rr.Value = arr
        arr = SortArray(rr)
        DoEvents
    Loop
End Sub

Private Sub MorningMax(arr As Variant, nMax As Long, dtMorning As Double, rr As Range)
    Dim ym As Long
    Dim ye As Long
    Do
        ym = MorningMaxIndex(arr, dtMorning)
        If ym <= nMax Then Exit Do
        ye = ym * Rnd() + 1
        arr(ye, 1) = Empty
        rr.Value = arr
        arr = SortArray(rr)
        DoEvents
    Loop
End Sub

Private Function MorningMaxIndex(arr As Variant, dtMorning As Double)
    Dim ym As Long
    For ym = 1 To UBound(arr, 1)
        If arr(ym, 1) > dtMorning Then Exit For
    Next
    MorningMaxIndex = ym - 1
End Function

Private Sub Less15(arr As Variant, deltat As Double)
    Dim y1 As Long
    Dim y2 As Long
    For y1 = 1 To UBound(arr, 1) - 1
        If Not IsEmpty(arr(y1, 1)) Then
            For y2 = y1 + 1 To UBound(arr, 1)
                If arr(y2, 1) - arr(y1, 1) < deltat Then
                    arr(y2, 1) = Empty
                Else
                    Exit For
                End If
            Next
        End If
    Next
End Sub

Private Function SortArray(rr As Range) As Variant
    Dim st As Sort
    Set st = rr.Parent.Sort
    With st
        .SortFields.Clear
        .SortFields.Add Key:=rr, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SetRange rr
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    SortArray = rr.Value
End Function

Private Function GetRndArr() As Variant
    Randomize
    Dim arr As Variant
    ReDim arr(1 To 30, 1 To 1)
    Dim yy As Long
    For yy = 1 To UBound(arr, 1)
        arr(yy, 1) = Rnd
    Next
    
    GetRndArr = arr
End Function
 
Код
Sub Макрос1()
    Cells.Clear: Randomize: For i = 1 To 30: Cells(i, 1).Value = TimeSerial(Int((24 * Rnd) + 1), Int(60 * Rnd), 0): Cells(i, 1).NumberFormat = "hh:mm": Next i
    Columns("A:A").Sort Columns(1), xlAscending, Header:=xlNo
    Columns("A:A").AutoFilter Field:=1, Criteria1:=">=00:00", Operator:=xlAnd, Criteria2:="<00:01"
    Columns("A:A").AutoFilter Field:=1, Criteria1:=">=07:00", Operator:=xlAnd, Criteria2:="<=23:59"
    Columns("A:A").AutoFilter Field:=1, Criteria1:=">=00:01", Operator:=xlAnd, Criteria2:="<07:00"
    Columns("A:A").AutoFilter
End Sub
Страницы: 1
Наверх