Рандом числа

robengo

Client
Регистрация
21.03.2023
Сообщения
138
Благодарностей
23
Баллы
18
В общем, у меня есть список допустим в нем 3 строки:
1
2
3
4

Я беру из списка случайную сроку, допустим он взял 3 и все его как будто зацикливает на этой цифре, в 80% случаев он будет выдавать 3.
Никто такого не замечал?

Бывало даже такое, 2 миллиона строк в файле, а он как будто упрется в районе 50 строк и берет только их в рабочий поток.

Поставил перемешивать список перед взятием, вроде стало лучше, но интересно у кого как?
 

Maxxm

Client
Регистрация
24.08.2021
Сообщения
187
Благодарностей
58
Баллы
28

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
Генери рандом перед кубиком взятия строки
 

robengo

Client
Регистрация
21.03.2023
Сообщения
138
Благодарностей
23
Баллы
18

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
Ну можно проверить, сделай тестовый шаблон на 1кк генераций рандом числа и проверь распределение. Если есть перекос будет сразу видно
 

robengo

Client
Регистрация
21.03.2023
Сообщения
138
Благодарностей
23
Баллы
18
122739


Вот пример, нет ни одной четверки и как можно заметить очень часто одну и туже цифру дает два раза подряд
 

White trash

Client
Регистрация
09.06.2014
Сообщения
835
Благодарностей
364
Баллы
63

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
Посмотреть вложение 122739

Вот пример, нет ни одной четверки и как можно заметить очень часто одну и туже цифру дает два раза подряд
Это не пример. 18 рандом чисел не дадут выборку нормальную, сгенери хотя-бы 10 тысяч штук, тогда можно будет о чём-то говорить. А лучше миллион
 

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
Вот рандом стандартным кубиком на 10к чисел от 1 до 6, вполне адекватное распределение
122743
 
  • Спасибо
Реакции: robengo

robengo

Client
Регистрация
21.03.2023
Сообщения
138
Благодарностей
23
Баллы
18

loogle

Client
Регистрация
08.12.2013
Сообщения
294
Благодарностей
115
Баллы
43
А если так через си шарп?
C#:
Random rnd = new Random(Guid.NewGuid().GetHashCode());
lock(rnd)
{
    project.Variables["var_ZP1"].Value = rnd.Next(1, 10).ToString();
    //
}
Переменную var_ZP1 нужно заранее создать.
 

Вложения

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
присоединяюсь - запустил рандом, значение пишу в базу, посмотрим что получится после 10к значений +-
 

Вложения

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
А если так через си шарп?
На самом деле неважно как, ситуация будет такая-же. Слишком короткие выборки, подобные ситуации будут в любом случае. Если необходимо исключить такое, то нужно просто учитывать что после генерации числа Х запрещена его генарация на протяжении нескольких следующих итераций.
 

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
запустил вот такой кубик от 0 до 9

кубик каждое значение пишет в sql

на sql стоит power bi

кол-во id - это кол - во записей

значения - ну это значений )))

ну пока в распределении не виду ничего такого, если честно

оставлю пока скрипт поработать до нормальных цифр
 

Вложения

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
но вообще, одно открытие я уже для себя сделал

стоит от 0 до 9

в кубике судя по всему последнее значение не включительно, а первое включительно

смотрите у меня 0 есть, а вот 9 - нет вообще

что при коротких задачах - например

рандом от 1 до 3 и надо получить рандом 33% - в таких задачах и на малеком диапазоне рандома - кубик будет обманывать судя по всему
 

Вложения

Ribas

Client
Регистрация
31.05.2014
Сообщения
1 440
Благодарностей
503
Баллы
113
кубик будет обманывать судя по всему
Ничего он обманывать не будет, всегда так было - число "от" включено в диапазон генерации, число "до" не включено. Нужно просто это иметь ввиду
 

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
Ничего он обманывать не будет, всегда так было - число "от" включено в диапазон генерации, число "до" не включено. Нужно просто это иметь ввиду
я почему то думал что все включительно )))) зы
 

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
после 5к значений - могу сказать, что распределение рандома - равномерное
 

Вложения

  • Спасибо
Реакции: Ribas

t79

Client
Регистрация
29.04.2024
Сообщения
255
Благодарностей
135
Баллы
43
10к значений

что могу сказать - рандом )
 

Вложения

Ylvov

Client
Регистрация
23.01.2017
Сообщения
91
Благодарностей
15
Баллы
8
Работа криптографически стойкого генератора случайных чисел

Генерация 1000000
от 1 до 6

C#:
void DemonstrateSecureRandomness()
{
    int totalIterations = 1000000;
    int minValue = 1;
    int maxValue = 6;
    int[] counts = new int[maxValue - minValue + 1];
    
        project.SendInfoToLog($"Генерируем {totalIterations} случайных чисел от {minValue} до {maxValue}");
    
    for (int i = 0; i < totalIterations; i++)
    {
        int randomNumber = GenerateSecureRandomNumber(minValue, maxValue);
        counts[randomNumber - minValue]++;
        if (i < 20 || i > totalIterations - 20)
        {
            project.SendInfoToLog($"Итерация {i + 1}: Сгенерировано число {randomNumber}");
        }
        else if (i == 20)
        {
            project.SendInfoToLog("...");
        }
    }
    
    project.SendInfoToLog("\nРезультаты:");
    for (int i = 0; i < counts.Length; i++)
    {
        double percentage = (double)counts[i] / totalIterations * 100;
        project.SendInfoToLog($"Число {i + minValue}: {counts[i]} раз ({percentage:F2}%)");
    }
    
    double expectedPercentage = 100.0 / (maxValue - minValue + 1);
    double maxDeviation = 0;
    for (int i = 0; i < counts.Length; i++)
    {
        double deviation = System.Math.Abs((double)counts[i] / totalIterations * 100 - expectedPercentage);
        if (deviation > maxDeviation)
        {
            maxDeviation = deviation;
        }
    }
    
    project.SendInfoToLog($"\nМаксимальное отклонение от ожидаемого значения: {maxDeviation:F2}%");
    if (maxDeviation < 1)
    {
        project.SendInfoToLog("Распределение очень близко к равномерному", true);
    }
    else if (maxDeviation < 2)
    {
        project.SendInfoToLog("Распределение близко к равномерному", true);
    }
    else
    {
        project.SendInfoToLog("Распределение может быть неравномерным", false);
    }
    
    double chiSquare = 0;
    for (int i = 0; i < counts.Length; i++)
    {
        double expected = expectedPercentage * totalIterations / 100;
        chiSquare += System.Math.Pow(counts[i] - expected, 2) / expected;
    }
    project.SendInfoToLog($"\nЗначение хи-квадрат: {chiSquare:F4}");
    project.SendInfoToLog("Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815");
    if (chiSquare < 7.815)
    {
        project.SendInfoToLog("Распределение статистически равномерно", true);
    }
    else
    {
        project.SendInfoToLog("Распределение статистически неравномерно", false);
    }
}

int GenerateSecureRandomNumber(int minValue, int maxValue)
{
    if (minValue > maxValue)
        throw new System.ArgumentOutOfRangeException("minValue");
    if (minValue == maxValue)
        return minValue;

    var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
    long range = (long)maxValue - minValue + 1;
    byte[] uint32Buffer = new byte[4];
    while (true)
    {
        rng.GetBytes(uint32Buffer);
        uint randomUInt = System.BitConverter.ToUInt32(uint32Buffer, 0);

        long result = (long)(randomUInt % range);
        if (randomUInt - result + (range - 1) >= randomUInt)
        {
            return (int)(minValue + result);
        }
    }
}

// Вызов функции демонстрации
DemonstrateSecureRandomness();
Результат:
Число 1: 166676 раз (16,67%)
Число 2: 166640 раз (16,66%)
Число 3: 166721 раз (16,67%)
Число 4: 166828 раз (16,68%)
Число 5: 166382 раз (16,64%)
Число 6: 166753 раз (16,68%)

Максимальное отклонение от ожидаемого значения: 0,03%
Значение хи-квадрат: 0,7096
Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815
Распределение статистически равномерно
 

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
772
Благодарностей
515
Баллы
93
Работа криптографически стойкого генератора случайных чисел

Генерация 1000000
от 1 до 6

C#:
void DemonstrateSecureRandomness()
{
    int totalIterations = 1000000;
    int minValue = 1;
    int maxValue = 6;
    int[] counts = new int[maxValue - minValue + 1];
   
        project.SendInfoToLog($"Генерируем {totalIterations} случайных чисел от {minValue} до {maxValue}");
   
    for (int i = 0; i < totalIterations; i++)
    {
        int randomNumber = GenerateSecureRandomNumber(minValue, maxValue);
        counts[randomNumber - minValue]++;
        if (i < 20 || i > totalIterations - 20)
        {
            project.SendInfoToLog($"Итерация {i + 1}: Сгенерировано число {randomNumber}");
        }
        else if (i == 20)
        {
            project.SendInfoToLog("...");
        }
    }
   
    project.SendInfoToLog("\nРезультаты:");
    for (int i = 0; i < counts.Length; i++)
    {
        double percentage = (double)counts[i] / totalIterations * 100;
        project.SendInfoToLog($"Число {i + minValue}: {counts[i]} раз ({percentage:F2}%)");
    }
   
    double expectedPercentage = 100.0 / (maxValue - minValue + 1);
    double maxDeviation = 0;
    for (int i = 0; i < counts.Length; i++)
    {
        double deviation = System.Math.Abs((double)counts[i] / totalIterations * 100 - expectedPercentage);
        if (deviation > maxDeviation)
        {
            maxDeviation = deviation;
        }
    }
   
    project.SendInfoToLog($"\nМаксимальное отклонение от ожидаемого значения: {maxDeviation:F2}%");
    if (maxDeviation < 1)
    {
        project.SendInfoToLog("Распределение очень близко к равномерному", true);
    }
    else if (maxDeviation < 2)
    {
        project.SendInfoToLog("Распределение близко к равномерному", true);
    }
    else
    {
        project.SendInfoToLog("Распределение может быть неравномерным", false);
    }
   
    double chiSquare = 0;
    for (int i = 0; i < counts.Length; i++)
    {
        double expected = expectedPercentage * totalIterations / 100;
        chiSquare += System.Math.Pow(counts[i] - expected, 2) / expected;
    }
    project.SendInfoToLog($"\nЗначение хи-квадрат: {chiSquare:F4}");
    project.SendInfoToLog("Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815");
    if (chiSquare < 7.815)
    {
        project.SendInfoToLog("Распределение статистически равномерно", true);
    }
    else
    {
        project.SendInfoToLog("Распределение статистически неравномерно", false);
    }
}

int GenerateSecureRandomNumber(int minValue, int maxValue)
{
    if (minValue > maxValue)
        throw new System.ArgumentOutOfRangeException("minValue");
    if (minValue == maxValue)
        return minValue;

    var rng = System.Security.Cryptography.RandomNumberGenerator.Create();
    long range = (long)maxValue - minValue + 1;
    byte[] uint32Buffer = new byte[4];
    while (true)
    {
        rng.GetBytes(uint32Buffer);
        uint randomUInt = System.BitConverter.ToUInt32(uint32Buffer, 0);

        long result = (long)(randomUInt % range);
        if (randomUInt - result + (range - 1) >= randomUInt)
        {
            return (int)(minValue + result);
        }
    }
}

// Вызов функции демонстрации
DemonstrateSecureRandomness();
Результат:
Число 1: 166676 раз (16,67%)
Число 2: 166640 раз (16,66%)
Число 3: 166721 раз (16,67%)
Число 4: 166828 раз (16,68%)
Число 5: 166382 раз (16,64%)
Число 6: 166753 раз (16,68%)

Максимальное отклонение от ожидаемого значения: 0,03%
Значение хи-квадрат: 0,7096
Для 3 степеней свободы и уровня значимости 0.05, критическое значение хи-квадрат равно 7.815
Распределение статистически равномерно
Решение конечно крутое, но зачем так сложно?
Берешь первое значение, работаешь с ним, кладешь в конец списка и все, эффект тот же самый реализация в разы проще :-)
 

Кто просматривает тему: (Всего: 5, Пользователи: 0, Гости: 5)