Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
Faltfromoss
0 / 0 / 1
Регистрация: 28.03.2014
Сообщений: 36
1

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

29.06.2014, 14:10. Просмотров 2142. Ответов 16
Метки нет (Все метки)

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

Генератор случайных чисел
Здравствуйте! Кто-нибудь объясните пожалуйста. Вот есть функция rand(). Она...

Генератор случайных чисел
Здорова господа! Нужно написать свой собственный генератор случайных чисел,...

Генератор случайных чисел
Здравствуйте, для программы мне требуется генератор, который будет задавать...

Генератор случайных чисел
Есть функция, генерирующая случайные целые числа с помощью линейного...

Генератор случайных чисел
Добрый вечер! Собственно-то тако задание: необходимо правильно задать параметры...

16
Убежденный
Ушел с форума
Эксперт С++
15998 / 7269 / 1180
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
29.06.2014, 14:15 2
Сгенерировать один rand и использовать его как диапазон для второго rand.
0
Kerry_Jr
Эксперт PHP
2210 / 2006 / 940
Регистрация: 14.05.2014
Сообщений: 5,869
Записей в блоге: 1
Завершенные тесты: 5
29.06.2014, 14:17 3
От m до n
C++
1
rand() % (n - m + 1) + m
А в чем проблема-то?
0
Vladimir.
158 / 158 / 48
Регистрация: 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)
0
Faltfromoss
0 / 0 / 1
Регистрация: 28.03.2014
Сообщений: 36
29.06.2014, 14:24  [ТС] 5
Цитата Сообщение от Kerry_Jr Посмотреть сообщение
А в чем проблема-то?
Проблема в том, что в этот код я могу подставить границы одного, диапазона, например m=5, n=15 и rand() будет возвращать числа от 5 до 15 и всё. А мне нужно, к примеру, чтобы помимо этого диапазона от 5 до 15-ти он возвращал числа еще из другого диапазона, к примеру от 23 до 42 тоже случайным образом

Цитата Сообщение от Убежденный Посмотреть сообщение
Сгенерировать один rand и использовать его как диапазон для второго rand.
Немного не понял ход мысли. :\
0
SlavaSSU
217 / 162 / 47
Регистрация: 17.07.2012
Сообщений: 587
29.06.2014, 14:26 6
Faltfromoss, как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них xD
0
Faltfromoss
0 / 0 / 1
Регистрация: 28.03.2014
Сообщений: 36
29.06.2014, 14:28  [ТС] 7
Цитата Сообщение от SlavaSSU Посмотреть сообщение
Faltfromoss, как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них xD
Я сейчас больше к этому варианту и склоняюсь, других пока не вижу.
0
astronomydomine
0 / 0 / 0
Регистрация: 17.09.2013
Сообщений: 3
29.06.2014, 14:29 8
Есть вариант написать цикл, в котором программа генерирует число в диапазоне от минимального до максимального числа из данных диапазонов и каждый раз проверяет, если оно не входит в один из диапазонов, то снова генерирует до тех пор, пока не появится нужное число. Просто это много времени займет.
0
Kerry_Jr
Эксперт PHP
2210 / 2006 / 940
Регистрация: 14.05.2014
Сообщений: 5,869
Записей в блоге: 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, такая же идея пришла в голову
1
Faltfromoss
0 / 0 / 1
Регистрация: 28.03.2014
Сообщений: 36
29.06.2014, 14:40  [ТС] 10
Kerry_Jr, согласен, как вариант тоже вполне применимый.
0
0x10
2571 / 1751 / 288
Регистрация: 24.11.2012
Сообщений: 4,377
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
0
ValeryS
Модератор
7264 / 5518 / 692
Регистрация: 14.02.2011
Сообщений: 18,691
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;
 
}
1
Убежденный
Ушел с форума
Эксперт С++
15998 / 7269 / 1180
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
29.06.2014, 14:47 13
Цитата Сообщение от Faltfromoss Посмотреть сообщение
Немного не понял ход мысли. :\
Пусть есть N диапазонов, у каждого свои min- и max-значения.
Генерируем первое случайное число от 1 до N - это будет номер диапазона.
А затем второе случайное число от min до max внутри выбранного диапазона.

0x10 расписал уже все выше, добавить нечего.
0
zss
Модератор
Эксперт С++
7186 / 6681 / 4230
Регистрация: 18.12.2011
Сообщений: 17,629
Завершенные тесты: 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;
0
Vladimir.
158 / 158 / 48
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 14:50 15
как варик, сгенерить первый ранд из 1 диапазона, сгенерить 2 ранд из 2 диапазона, а потом рандомно выбать один из них
Есть вариант написать цикл, в котором программа генерирует число в диапазоне от минимального до максимального числа из данных диапазонов и каждый раз проверяет...
работать оно конечно будет, но нехорошо так делать совсем(с)

пишем функцию вычисления длинны диапазона, находим суммарную длину всех диапазонов, бросаем кость по суммарной длине, вычисляем в какой диапазон и элемент попали. Такой способ будет работать во первых быстро, во вторых не будет нарушать тип распределения.
1
aleks_tar
2 / 2 / 2
Регистрация: 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;
}
0
Vladimir.
158 / 158 / 48
Регистрация: 24.11.2009
Сообщений: 375
29.06.2014, 15:43 17
aleks_tar, пусть диапазоны {1,2} и {5, 10000000},
вопрос:
1.) во сколько раз 1 будет выпадать чаще 5 ?
2.) так должно быть?
0
29.06.2014, 15:43
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.06.2014, 15:43

генератор случайных чисел
Всем доброго времени суток, вот решил написать генератор чисел длины 768 бит,...

Генератор случайных чисел
составить генератор случайных чисел, имеющий два члена - границы...

генератор случайных чисел
как реализовать генератор случайных чисел? чтобы можно было вводить два...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru