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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.90
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 675
Регистрация: 29.11.2010
Сообщений: 12,328
#1

std::random_device - C++

17.11.2012, 19:02. Просмотров 4511. Ответов 37

Здравствуйте.
Я так понимаю, Windows, в отличии от линя, не предоставляет специльное устройство для недетерминированных случайных чисел. Т.е. запись
C++
1
std::random_device rd;
под виндой ругается и кидает ексепшн. Неужели ф-ция из стандартной библиотеки писалась лишь для использования под никсы ? (приятно конечно, но лишь отчасти)
Как на винде то получить недетерминированное число, или прийдется довольствоваться следующей записью ?
C++
1
2
std::mt19937 gen;
gen.seed (time (0));
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.11.2012, 19:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос std::random_device (C++):

std::random_device падает приложение - C++
win7, gcc 4.4.7 пишет, ошибка "std::runtime_error" чего ему надо? Добавлено через 14 часов 17 минут вверх

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream - C++
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++ 2005 Express Edition. Образ диска...

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri - C++
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

STL std::set, std::pair, std::make_pair - C++
Я не знаю как описать тему в двух словах, поэтому не обращайте внимание на название темы. Собственно перейдем к нашим баранам: есть...

На основе исходного std::vector<std::string> содержащего числа, создать std::vector<int> с этими же числами - C++
подскажите есть вот такая задача. Есть список . Создать второй список, в котором будут все эти же числа, но не в виде строк, а в виде...

(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const& - C++
astxx::manager::connection::connection(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned short); ...

37
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 675
Регистрация: 29.11.2010
Сообщений: 12,328
18.11.2012, 03:25  [ТС] #16
Цитата Сообщение от alex_x_x Посмотреть сообщение
ok, я посмотрел в описание и удивлен еще больше
что ты делаешь:
ты создаешь std::random_device

для того чтобы (sic!) инициализировать другой генератор случайных чисел
rd() - генерирует псевдослучайное число, которое используется для инициализации второго генератора
Ну да, а также можно инициализировать gen.seed (time (0)). Оно берет число, отталкиваясь от которого генерирует случайные числа, если брать константу, то будет генерировать уже не псевдослучайные числа, а каждый раз показывать одинаковый результат. Нам не нужно использовать всю мощь random_device, нам хватит взять лишь одно недетерменированное число, а на основе него уже создавать другие случайные числа.

Добавлено через 4 минуты
Генератор СЧ нужно же как то инициализировать. Почему вас смущает тот факт, что инициализировать будет результат другого ГСЧ, недетерменированного. На srand (time (0)) никто не орет, хотя принцип действия тот же.
0
alex_x_x
бжни
2449 / 1654 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 03:30 #17
понимаешь в чем соль - для инициализации ПГСЧ нужно всего лишь уникальное число
использовать для инициализации ПГСЧ генератор более случайных чисел (грубо говоря) накладно и бессмысленно
тем более такой может быть и не реализован

хотя я вижу подобный пример на том же cppreference.com, но все же мне кажется это неправильно

Добавлено через 1 минуту
Цитата Сообщение от MrGluck Посмотреть сообщение
Почему вас смущает тот факт, что инициализировать будет результат другого ГСЧ, недетерменированного. На srand (time (0)) никто не орет, хотя принцип действия тот же.
Потому что это бессмысленно

из этой вашей википедии

на свойства последовательности псевдо случайных чисел влияет уникальность инициализатора, а не его природа
time(0) в-принципе достаточно уникален, так что все норм

из этой вашей википедии
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <boost/random.hpp>
#include <ctime>
 
using namespace boost;
 
double SampleNormal (double mean, double sigma)
{
    // выбор генератора случайных чисел
    mt19937 rng;
    // инициализация генератора числом секунд с 1970 года
    rng.seed(static_cast<unsigned> (std::time(0)));
 
    // выбор нужного распределения
    normal_distribution<double> norm_dist(mean, sigma);
 
    // привязка генератора к распределению
    variate_generator<mt19937&, normal_distribution<double> >  normal_sampler(rng, norm_dist);
 
    // пример работы
    return normal_sampler();
}
0
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 675
Регистрация: 29.11.2010
Сообщений: 12,328
18.11.2012, 03:49  [ТС] #18
alex_x_x, да, есть возможность обойтись без этого, но использование ГСЧ для инициализации добавляет ++ к "случайности". Оно, естественно не делает ГПСЧ ГСЧ (понятно, что истинного ГСЧ не существует, но иначе получилась бы каша в терминах), но начало распределения уже становится неслучайным. Чем инициализировать, все же, по-моему, остается делом вкуса, но думаю не нужно спорить о том, что случайности time(0) может не хватать.

P.S. именно оттуда я и взял способ инициализации, но тогда я не ставил это под сомнение, а принял как данность.
0
soon
2542 / 1307 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
18.11.2012, 09:07 #19
C++
1
2
3
4
5
6
7
#include <random>
 
int main()
{
    std::mt19937(std::random_device().operator()());
    return 0;
}
Как-то фигово выглядит.
0
Nick Alte
Эксперт С++
1639 / 1011 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
18.11.2012, 09:17 #20
Цитата Сообщение от MrGluck Посмотреть сообщение
понятно, что истинного ГСЧ не существует
Ну как же не существует, когда random_device - это он и есть.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 675
Регистрация: 29.11.2010
Сообщений: 12,328
18.11.2012, 14:03  [ТС] #21
Цитата Сообщение от soon Посмотреть сообщение
C++
1
2
3
4
5
6
7
#include <random>
 
int main()
{
    std::mt19937(std::random_device().operator()());
    return 0;
}
Как-то фигово выглядит.
Почему фигово?

Цитата Сообщение от Nick Alte Посмотреть сообщение
Ну как же не существует, когда random_device - это он и есть.
Это споры о терминах, std::random_device также завязан на каких-либо процессах, а для получения истинно случайного числа надо абстрагироваться от всего. Естественно, сделать такое на ЭВМ просто невозможно. Но его случайности хватает для решения задач (возможно даже и не всех), требующих больший рандом, нежели ГПСЧ, именно поэтому, слово псевдо и убирают. Но от этого случайные числа, генерируемые random_device не становятся истинными, они лишь более случайны и удовлетворяют необходимым условиям в решении конкретной задачи.
0
alex_x_x
бжни
2449 / 1654 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
18.11.2012, 14:42 #22
Цитата Сообщение от MrGluck Посмотреть сообщение
Это споры о терминах, std::random_device также завязан на каких-либо процессах, а для получения истинно случайного числа надо абстрагироваться от всего. Естественно, сделать такое на ЭВМ просто невозможно.
опять нет
random_number может использовать аппаратный ГСЧ, а там будут истинно случайные последовательности

Цитата Сообщение от MrGluck Посмотреть сообщение
Но его случайности хватает для решения задач (возможно даже и не всех), требующих больший рандом, нежели ГПСЧ, именно поэтому, слово псевдо и убирают.
это разные вещи в-принципе
/dev/random генерирует настоящие случайные числа по всяким флуктуациям и биениям в железе
остальные генераторы используют всякие линейные конгруэнтные методы для генерации последовательностей, которые:
- требуют инициализатора, чтобы завести уникальную последовательность
- обладают всякими плохими свойствами (некоторой зависимостью между элементами, повторяемостью через некоторый большой период)

аппаратные ГСЧ и ПГСЧ это разные вещи
использовать ПГСЧ для инициализации ГСЧ - ну такого я еще не слышал (почему тогда просто ГСЧ не использовать?)

/dev/random и /dev/urandom — специальные символьные псевдоустройства в некоторых UNIX-подобных системах, впервые появившиеся в ядре Linux версии 1.3.30. Они предоставляют интерфейс к системному генератору случайных чисел, который выводит шумы из драйверов устройств и других источников в «хаотичный» пул (англ. entropy pool). Генератор также сохраняет необходимое количество битов шума в этом пуле и формирует из него случайные числа.

При чтении данных в устройстве /dev/random создаются только случайные байты, состоящие из битов шума «хаотичного» пула. Устройство /dev/random может быть необходимо пользователям, которые требуют очень высокого коэффициента случайности, например, при создании ключа доступа и т. п. Если «хаотичный» пул опустел, чтение /dev/random блокируется, пока необходимое количество битов в пуле не будет создано.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7427 / 4542 / 675
Регистрация: 29.11.2010
Сообщений: 12,328
18.11.2012, 15:09  [ТС] #23
Цитата Сообщение от alex_x_x Посмотреть сообщение
использовать ПГСЧ для инициализации ГСЧ - ну такого я еще не слышал (почему тогда просто ГСЧ не использовать?)
Никто ГПСЧ для ГСЧ не использует. Скорее ГСЧ для инициализации ГПСЧ. А просто ГСЧ нет смысла использовать все время, хватает лишь единожды, но я это уже расписывал выше.

Не по теме:

Шумы тоже имеют зависимость, все влияет на все, различна лишь степень влияния. Для решения определенных задач люди договариваются называть СЧ истинно случайными, если эта степень не превышает нужной погрешности. Некоторые физики с помощью движений и состояний атомов генерят СЧ и называют лишь их истинно случайными. У нас разные представления о связях объектов в мире. Я верю, что все взаимосвязано и все происходит так из-за стремящегося в бесконечность ряда предшествующих событий, поэтому не признаю истинно случайных чисел, лишь соглашаюсь для удобства решения задачи.



Думаю пора прекращать оффтоп. В том, что std::random_device - ГСЧ, а std::mt19937 - ГПСЧ мы сходимся во мнениях, остальное уже философия)

Подытожу, если у кого-то будет схожая с моей проблема:
std::random_device требует использование аппаратного устройства. На Linux это dev/urandom или dev/random, поэтому в реализации на gcc в конструкторе вызывается попытка инициализации данных устройств, и, если этого не удается - кидается эксепшн. При портировании на windows, MinGW еще не до конца доработали, и конструктор все так же пытается получить доступ к данным устройствам, коих естественно на винде нет, отсюда и возникает ошибка. В компиляторе VS random.h реализован по своему, подстроен под винду и все работает нормально. Также в boost/random конструктор ведет себя по разному, в зависимости от ОС, что позволяет использовать его на различных ОС. Можно сказать, что это универсальное решение. Его я и использовал, проблема решена.
0
soon
2542 / 1307 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
18.11.2012, 19:01 #24
Цитата Сообщение от MrGluck Посмотреть сообщение
Почему фигово?
Имхо, хуже, чем
C++
1
2
std::random_device rd;
std::mt19937 gen(rd());
Не стоит одна переменная такого.
1
_andrew_
22 / 22 / 3
Регистрация: 14.11.2012
Сообщений: 64
19.11.2012, 16:55 #25
ВСЕ РАБОТАЕТ! XP!!!:
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
#include <iostream>
#include<conio.h>
#include<cstdlib>
using namespace std;
int main()
{
    int magic;    // Магическое число
    int guess;    // Вариант пользователя
   
    magic=rand()%12;        // Получаем магическое число       ВОТ ОНА!!!
     
    cout<<" Vvedite svoy variant magicheskogo chisla ";
    cin>>guess;
    if(guess==magic)
    cout<<"** Pravilno !!! Vi ugadali magicheskoye chislo!!! ** "<<'\n';
    else cout<<" Vi oshiblis' !!! ";
    if(guess>magic)
    {
                   cout<<" Vashe chislo bolshe" ;
                   cout<<" magicheskogo chisla !!! ";
                   }
                   if(guess<magic) cout<<"Vashe chislo menshe magicheskogo chisla !!!";
    
   getch(); 
    return 0;
    
}
0
Миниатюры
std::random_device  
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
19.11.2012, 18:43 #26
_andrew_, Клево конечно, очень за вас рады, но не стоит писать о том, суть чего не понимаете.
0
Jupiter
19.11.2012, 19:36
  #27

Не по теме:

Цитата Сообщение от _andrew_ Посмотреть сообщение
ВСЕ РАБОТАЕТ! XP!!!:
вот пичалька! а у меня на stm cortex m4 не работает, помоги, чё делать бро?

1
MrGluck
19.11.2012, 19:53  [ТС]
  #28

Не по теме:

Jupiter, наверняка забыл

C++
1
#include "stdafx.h"

0
Vourhey
19.11.2012, 19:55
  #29

Не по теме:

_andrew_, повеселил, зачет.

0
Somebody
2791 / 1602 / 147
Регистрация: 03.12.2007
Сообщений: 4,198
Завершенные тесты: 1
19.11.2012, 20:18 #30
Цитата Сообщение от soon Посмотреть сообщение
Имхо, хуже, чем
C++
1
2
std::random_device rd;
std::mt19937 gen(rd());
Не стоит одна переменная такого.
А как насчёт
C++
1
std::mt19937 gen{std::random_device()()};
?
2
19.11.2012, 20:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2012, 20:18
Привет! Вот еще темы с ответами:

Реализация класса MyString. Стандартная библиотека, std::string, std::vector - C++
как добавить реализацию конкатенации строк через перегрузку оператора &quot;+=&quot; в классе MyString и почему ошибка выдается???#include...

Как искать по std::vecotr из std::pait по одному значению из пары? - C++
? :) Пункт 4.7 Правил: Как можно более полно описывайте суть проблемы или вопроса, что было сделано для ее решения и какие результаты...

что использовать std::cout или просто using namespace std? - C++
Приветствую! Сейчас учу С++, постигаю азы так сказать. В арсенале две книги - Джефф Кент, &quot;Основы программирования &quot; и Х.М....

Передача функции указатель на элемент std::vector<std::string> - C++
Доброй ночи тем, кому не спится (или живет в другом часовом поясе:p)! Есть функция, требующая в качестве параметра указатель на...


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

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

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