Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
1 / 1 / 0
Регистрация: 15.01.2014
Сообщений: 15

Реализация Random(a,b) вызовами Random(0,1) (задача 5.1-2 из Кормен изд.2)

23.03.2014, 15:18. Показов 840. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Покритикуйте результат. Вроде "на глаз" получается равномерное распределение.
Во-первых, если я правильно понял Random(0,1) - должна возвращать либо 0, либо 1.

Во-вторых, изначально я пробовал, подсчитать количество нужных разрядов в диапазоне a...b:
- так и не придумал как это сделать, кроме как найти позицию старшего бита проходя по числу в цикле;
- но это не помогло, так как непонятно, как обеспечить равномерное распределение имея произвольное максимальное число.

В-третьих, упростил себе задачу выбрав беззнаковые типы.

Придумал только взять тип большей разрядности, заполнить его биты вызовами Random(0,1) и преобразовать к нужному диапазону, ещё пришлось двигать диапазон на единицу вправо и, при возвращении результата влево, так как вероятность появления числа == 0 крайне низка.

В результате получается О(1) - не зависит от диапазона a...b, но толку от этого вроде нет, так как каждый вызов заполняет каждый бит "большого" типа.

Можно сделать что-то более правильное?

-----------
Вот код:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
typedef unsigned __int8 uint_small;
typedef unsigned __int64 uint_large;
 
typedef std::map<uint_small, int> distribution_map_t;
typedef distribution_map_t::iterator iter_distribution_map_t;
 
bool Random01()
{
    return rand() > (RAND_MAX / 2);
}
 
uint_small Random(uint_small a, uint_small b)
{
    assert( b > a );
    unsigned __int64 result = 0;
 
    ++b;
 
    for ( int j = 0; j < sizeof(uint_large) * 8; ++j )
    {
        result <<= 1;
        if ( Random01() )
            result += 1;
    }
 
    //if ( result == 0 ) // Не наблюдал, поэтому и двигаю ++b, --b и  a + res - 1;
        //return a;
 
    uint_small res = (uint_small)(result % (uint_large)(b - a));
 
    if ( res == 0 )
        return --b;
 
    return a + res - 1;
}
 
int main(int argc, char* argv[])
{
    uint_small uint_small_max = 0;
    memset((void*)&uint_small_max, 0xFF, sizeof(uint_small));
 
    distribution_map_t mp;
 
    while ( true )
    {
        int rand1 = rand() % uint_small_max;
        int rand2 = rand() % uint_small_max;
 
        assert(rand1 >= 0 && rand1 < uint_small_max);
        assert(rand2 >= 0 && rand2 < uint_small_max);
 
        if ( rand1 == rand2 )
            continue;
 
        if ( rand1 > rand2 )
            std::swap(rand1, rand2);
 
        mp.clear();
 
        {
            for ( int i = rand1; i <= rand2; ++i )
                mp.insert(std::make_pair(i, 0));
        }
 
        printf("range: %d...%d\n", rand1, rand2);
 
        const int howmanycalls = (rand2 - rand1) * 100; // это неважно, чем больше, тем точнее
 
        for ( int i = 0; i < howmanycalls; ++i )
        {
            uint_small res = Random((uint_small)rand1, (uint_small)rand2);
            assert(res >= (uint_small)rand1);
            assert(res <= (uint_small)rand2);
 
            iter_distribution_map_t it = mp.find(res);
            if ( it != mp.end() )
                ++(it->second);
            else
                assert(false);
        }
 
        { // Вывод результатов распределения
            iter_distribution_map_t it = mp.begin();
            iter_distribution_map_t itEnd = mp.end();
 
            for ( ; it != itEnd; ++it )
                printf("num: %d, count: %d\n", it->first, it->second);  
        }
    } // while ( true )
 
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.03.2014, 15:18
Ответы с готовыми решениями:

Что не так с 'Random' или There is no overloaded version of 'Random' that can be called with these arguments
Доброго времени суток! Я с программированием на &quot;Вы&quot;, поэтому очень прошу доходчиво объяснить, что не так с этой строчкой? Выводит ошибку:...

У меня непонятки с методами Math.random() и Random()
Задача : заполнить массив из 15 элементов случайным образом вещественными значениями х (-5 &lt;= x &lt;= 5) class Massiv { ...

Random, повторы при static Random(1 seed)
Добрый вечер. Использую private static readonly Random, так как крутится в цикле и если убрать static, будут повторы даже в указанием...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.03.2014, 15:18
Помогаю со студенческими работами здесь

Random и объекты класса (pseudo random)
Всем привет. Есть класс: typedef unsigned int ui; class Player { private: ui health;

Когда твой Random совсем не Random
Мой код ведет себя весьма странно. У меня есть список экземпляров класса в котором (Уж простите что я такое наделал) есть экземпляр другого...

Реализация класса Random
А можно где-нибудь посмотреть, как полностью реализован класс. Можно и на другом языке программирования.

Переделать Math.random() в random()
public static void CompMove() { int x = (int) (Math.random() * 3), y = (int) (Math.random() * 3); while (field == '0' || field ==...

Задача с Random
Здравствуйте! Помогите, пожалуйста, решить следующую задачку с Random: Нужно сделать так, чтобы считалась вероятность от 0.11 до 0.55,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru