Форум программистов, компьютерный форум CyberForum.ru

Генератор случайных чисел - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
29.06.2014, 14:10     Генератор случайных чисел #1
Еще одна тема о генераторе. Только вопрос, на который я пока не нашел ответа в других темах. Как сгенерировать случайное число в двух или более разных заданных диапазонах? Т. е. если мы стандартно описываем генерацию в диапазоне от m до n:
C++
1
rand() % (n+1-m) + m
то здесь всё ясно. Но мне нужно сгенерировать например число, которое будет входить в один из диапазанов, например от 1 до 10 или от 23 до 72 или от 123 до 140 и т. д. и т. п. Я пока похожих примеров не нашел. Либо оно никому не нужно кроме меня, либо решение на столько простое, что никто этим вопросом не задавался кроме меня. Либо хреново искал, тоже как вариант.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.06.2014, 14:10     Генератор случайных чисел
Посмотрите здесь:

C++ Генератор случайных чисел
C++ генератор случайных чисел
Генератор случайных чисел C++
Генератор случайных чисел C++
C++ генератор случайных чисел
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14209 / 6224 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
29.06.2014, 14:15     Генератор случайных чисел #2
Сгенерировать один rand и использовать его как диапазон для второго rand.
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1863 / 1659 / 578
Регистрация: 14.05.2014
Сообщений: 4,762
Записей в блоге: 1
Завершенные тесты: 5
29.06.2014, 14:17     Генератор случайных чисел #3
От m до n
C++
1
rand() % (n - m + 1) + m
А в чем проблема-то?
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 14:23     Генератор случайных чисел #4
Цитата Сообщение от Faltfromoss Посмотреть сообщение
либо решение на столько простое..
C++
1
2
3
4
5
std::random_device rd;
std::uniform_int_distribution<int> spread1 (23,72); // между 23 и 72
std::uniform_int_distribution<int> spread2 (123,140); // между 123 и 140
int rdnum1 = spread1(rd);
int rdnum2 = spread2(rd)
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
29.06.2014, 14:24  [ТС]     Генератор случайных чисел #5
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
А в чем проблема-то?
Проблема в том, что в этот код я могу подставить границы одного, диапазона, например m=5, n=15 и rand() будет возвращать числа от 5 до 15 и всё. А мне нужно, к примеру, чтобы помимо этого диапазона от 5 до 15-ти он возвращал числа еще из другого диапазона, к примеру от 23 до 42 тоже случайным образом

Цитата Сообщение от Убежденный Посмотреть сообщение
Сгенерировать один rand и использовать его как диапазон для второго rand.
Немного не понял ход мысли. :\
SlavaSSU
213 / 158 / 44
Регистрация: 17.07.2012
Сообщений: 580
29.06.2014, 14:26     Генератор случайных чисел #6
Faltfromoss, как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них xD
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
29.06.2014, 14:28  [ТС]     Генератор случайных чисел #7
Цитата Сообщение от SlavaSSU Посмотреть сообщение
Faltfromoss, как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них xD
Я сейчас больше к этому варианту и склоняюсь, других пока не вижу.
astronomydomine
0 / 0 / 0
Регистрация: 17.09.2013
Сообщений: 3
29.06.2014, 14:29     Генератор случайных чисел #8
Есть вариант написать цикл, в котором программа генерирует число в диапазоне от минимального до максимального числа из данных диапазонов и каждый раз проверяет, если оно не входит в один из диапазонов, то снова генерирует до тех пор, пока не появится нужное число. Просто это много времени займет.
Kerry_Jr
Модератор
 Аватар для Kerry_Jr
1863 / 1659 / 578
Регистрация: 14.05.2014
Сообщений: 4,762
Записей в блоге: 1
Завершенные тесты: 5
29.06.2014, 14:37     Генератор случайных чисел #9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <ctime>
#include <cstdlib>
 
int main()
{
    setlocale(LC_ALL, "");
    int n;
    srand(unsigned(time(NULL)));
    // Предположим, имеется три диапазона,
    // в один из которых должно входить число
    // берем минимальное и максимальное из всех диапазонов
    // и находим случайное, затем проверяем, входит ли оно
    // в один из диапазонов, если да - возвращаем, нет - проделываем это снова
    // Диапазоны 1-10, 23-79, 110-140
    while (true)
    {
        n = rand() % (140 -1 + 1) + 1;
        if ((n > 0 && n < 11) || (n > 22 && n < 80) || (n > 109 && n < 141)) break;
    }
    std::cout << n << std::endl;
    return 0;
}
Долго работает

Добавлено через 55 секунд
astronomydomine, такая же идея пришла в голову
Faltfromoss
0 / 0 / 0
Регистрация: 28.03.2014
Сообщений: 31
29.06.2014, 14:40  [ТС]     Генератор случайных чисел #10
Kerry_Jr, согласен, как вариант тоже вполне применимый.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
29.06.2014, 14:42     Генератор случайных чисел #11
Сообщение было отмечено автором темы, экспертом или модератором как ответ
astronomydomine, Kerry_Jr, жесть какая... Надеюсь, сами понимаете, что такие решения неприемлемы.

Добавлено через 2 минуты
Faltfromoss,
C++
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
#include <iostream>
#include <map>
#include <vector>
 
int main() {
    std::vector<std::pair<int, int>> ranges {
        {0, 10},
        {20, 25},
        {50, 60}
    };
    
    std::map<int, int> counters;
    
    for (int i = 0; i < 100000; ++i) {
        const int range_index = rand() % ranges.size();
        const auto& range = ranges[range_index];
        const int number = rand() % (range.second - range.first + 1) + range.first;
        ++counters[number];
    }
    
    for (const auto& item : counters) {
        std::cout << item.first << ": " << item.second << std::endl;
    }
    
    return 0;
}
http://ideone.com/3zvfgI
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,051
29.06.2014, 14:45     Генератор случайных чисел #12
хоть сто диапазонов
вот с таким подходом
C++
1
2
3
4
5
6
7
8
9
10
11
int m=rand()%2;
switch(m)
{
  case 0:
    n=rand()%(k0+1-p0)+p0;
    break;
  case 1:
    n=rand()%(k1+1-p1)+p1;
    break;
 
}
Убежденный
Системный программист
 Аватар для Убежденный
14209 / 6224 / 987
Регистрация: 02.05.2013
Сообщений: 10,368
Завершенные тесты: 1
29.06.2014, 14:47     Генератор случайных чисел #13
Цитата Сообщение от Faltfromoss Посмотреть сообщение
Немного не понял ход мысли. :\
Пусть есть N диапазонов, у каждого свои min- и max-значения.
Генерируем первое случайное число от 1 до N - это будет номер диапазона.
А затем второе случайное число от min до max внутри выбранного диапазона.

0x10 расписал уже все выше, добавить нечего.
zss
Модератор
Эксперт С++
 Аватар для zss
5950 / 5555 / 1786
Регистрация: 18.12.2011
Сообщений: 14,195
Завершенные тесты: 1
29.06.2014, 14:50     Генератор случайных чисел #14
Тогда еще вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
// Предположим, имеется три диапазона,
    // в один из которых должно входить число
    // берем сумму интервалов всех диапазонов
    // и находим случайное, затем проверяем, переходит ли оно границу,
    // если да - прибавляем пропускаемый интервал
    // Диапазоны 1-10, 23-79, 110-140
    // сумма интервалов 9+56+30=95
    n = rand() %95+1;
    if(n>10)
         n+=13;
    if(n>79)
         n+=31;
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 14:50     Генератор случайных чисел #15
как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них
Есть вариант написать цикл, в котором программа генерирует число в диапазоне от минимального до максимального числа из данных диапазонов и каждый раз проверяет...
работать оно конечно будет, но нехорошо так делать совсем(с)

пишем функцию вычисления длинны диапазона, находим суммарную длину всех диапазонов, бросаем кость по суммарной длине, вычисляем в какой диапазон и элемент попали. Такой способ будет работать во первых быстро, во вторых не будет нарушать тип распределения.
aleks_tar
2 / 2 / 0
Регистрация: 19.06.2014
Сообщений: 17
29.06.2014, 15:26     Генератор случайных чисел #16
Для диапазона используется класс Range со свойствами first_ и last_ (первый и последний), создаётся вектор, в который заносится необходимое количество элементов типа Range. Для генерации случайного числа вызывается функция getRandomInSeveralRanges(). В этой функции сначала случайным образом выбирается один из диапазонов, дальше в этом диапазоне случайным образом выбирается число. Данный пример работает только с целыми числами, но его, при желании, можно доработать, чтобы он работал, например, с числами с плавающей точкой.

C++
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
#include <cstdlib>
#include <vector>
#include <ctime>
#include <iostream>
 
class Range
{
    size_t first_;
    size_t last_;
public:
    Range(const size_t first, const size_t last)
    {
        first_ = first;
        last_ = last;
    }
    
    size_t getFirst() const
    {
        return first_;
    }
    
    size_t getLast() const
    {
        return last_;
    }
};
 
int getRandomInSeveralRanges(const std::vector<Range> ranges)
{
    size_t number_of_ranges = rand() % ranges.size();
    return rand() % (ranges.at(number_of_ranges).getLast() - 
        ranges.at(number_of_ranges).getFirst()) + 
        ranges.at(number_of_ranges).getFirst();
}
 
int main()
{
    // пример использования функции getRandomInSeveralRanges())
    std::vector<Range> ranges;
    ranges.push_back(Range(10, 20));
    ranges.push_back(Range(30, 40));
    // srand() нужно вызвать перед вызовом функции getRandomInSeveralRanges(),
    // но только один раз не зависимо от того, сколько раз после этого будет
    // вызвана эта функция 
    srand(time(NULL));
    for(int i = 0 ; i < 40; ++i)
    {
        std::cout << getRandomInSeveralRanges(ranges) << std::endl;
    }
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.06.2014, 15:43     Генератор случайных чисел
Еще ссылки по теме:

C++ Генератор случайных чисел
C++ Генератор случайных чисел
Генератор случайных чисел C++

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

Или воспользуйтесь поиском по форуму:
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 15:43     Генератор случайных чисел #17
aleks_tar, пусть диапазоны {1,2} и {5, 10000000},
вопрос:
1.) во сколько раз 1 будет выпадать чаще 5 ?
2.) так должно быть?
Yandex
Объявления
29.06.2014, 15:43     Генератор случайных чисел
Ответ Создать тему
Опции темы

Текущее время: 03:11. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru