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

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

Войти
Регистрация
Восстановить пароль
 
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 190
#1

Неравномерность распределения полученного с помощью rand() - C++

02.01.2017, 18:56. Просмотров 297. Ответов 11
Метки нет (Все метки)

Обнаружил странный баг в функции rand().
картинка 640х480 заполняется случайно ч/б пикселями построчно.
вот код и картинка:

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
#include <iostream>
#include "opencv2/opencv.hpp"
 
 
 
using namespace std;
using namespace cv;
 
int main(){
 
    Mat img = Mat(480, 640, CV_8UC1);
 
    for (int seed = 0; seed < 2000; seed += 10){
 
        srand(seed);
 
        for (int row = 0; row < img.rows; row++){
            for (int col = 0; col < img.cols; col++){
                img.at<uchar>(row, col) = 255 * (rand() % 2);
            }
        }
        cout << "seed: " << seed << endl;
        imshow("test", img);
        waitKey(1000);
 
    }
 
 
    cout << endl << endl;
    system("pause");
    return 0;
}
При разных значениях seed картинка меняется но не принципиально! полосы остаются!
и если например ширина картинки будет 645 то получается на глаз очень равномерный шум.
0
Миниатюры
Неравномерность распределения полученного с помощью rand()  
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.01.2017, 18:56
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Неравномерность распределения полученного с помощью rand() (C++):

Как задать диапазон с помощью функции rand? - C++
В задаче говорится &quot;Дан массив целых чисел (размер – случайное число из диапазона )&quot;. Как задать диапазон с помощью функции...

С помощью rand() сделать генератор дробных чисел - C++
srand(time(NULL)); rand()%1000; этот генератор генерирует целые числа, как сделать что-бы он генерировал нецелые числа до 3-х знаков...

Заполнить двумерный массив с помощью rand() и вывести его - C++
Всем привет, в общем обучение идет полным ходом и столкнулся с непонятным явлением. Пытаясь заполнить двумерный массив с помощью rand() и...

Нужно сгенерировать элементы массива случайным образом с помощью функции rand - C++
Нужно сгенерировать элементы случайным образом с помощью функции rand. Определить индексы максимального элемента матрицы. Вычислить...

Можно ли получить значение элемента кортежа полученного с помощью make_tuple - C++
Здравствуйте, есть массив it = make_tuple(i, j, false); Есть ли возможность получить третье значение (false) , зная лишь i и j

Найти ряд распределения полученного числа - Теория вероятностей
на карточках написаны цифры: 1, 2, и 3. наугад три раза (с возвратом) берется одна из карточек и находится сумма чисел, изображенных на...

11
cybeuser
55 / 105 / 43
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 19:02 #2
srand вынесети из цикла for

Добавлено через 1 минуту
зачем вы каждый раз инициализируете генератор?
0
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 190
02.01.2017, 19:10  [ТС] #3
Цитата Сообщение от cybeuser Посмотреть сообщение
srand вынесети из цикла for
к чему это? полосы есть при любом srand и при его отсутствии.

Добавлено через 6 минут
Думаю это просто баг алгоритма.
0
cybeuser
55 / 105 / 43
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 19:11 #4
nefton, это могло бы послужить равномерности

Добавлено через 19 секунд
в чем баг?
0
gazlan
3139 / 1915 / 285
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
02.01.2017, 19:16 #5
Это не баг, это фича ©

Linear congruential generator

Вместо встроенного PRNG используйте что-либо получше, например Mersenne Twister
0
nefton
44 / 20 / 5
Регистрация: 28.02.2013
Сообщений: 190
02.01.2017, 19:17  [ТС] #6
версия студии
0
Миниатюры
Неравномерность распределения полученного с помощью rand()  
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
02.01.2017, 19:40 #7
Цитата Сообщение от nefton Посмотреть сообщение
C++
1
img.at<uchar>(row, col) = 255 * (rand() % 2);
C++
1
img.at<uchar>(row, col) = 255 * (rand() / (RAND_MAX / 2 + 1));
Это баг, но твоего алгоритма. Потерял равномерное распределение - вот и получил такой результат.
0
cybeuser
55 / 105 / 43
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 19:57 #8
DrOffset, но ведь и так и так будет равномерное распределение, разве нет?

Добавлено через 10 минут
nefton, можно ли называть багом равномерность, используя генератор с равномерным распределением?
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
02.01.2017, 20:16 #9
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от cybeuser Посмотреть сообщение
но ведь и так и так будет равномерное распределение, разве нет?
Конечно нет.
Грубо обрезая диапазон [0, RAND_MAX] по модулю 2, мы его (равномерное распределение) теряем.
Вот неплохое объяснение: http://stackoverflow.com/a/10984975

Добавлено через 14 минут
Вообще, некорректность использования формулы rand() % N уже давно всем известна, странно называть это багом, когда такие вещи уже давно вынесены в FAQ; Например: http://c-faq.com/lib/randrange.html
3
cybeuser
55 / 105 / 43
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 20:22 #10
DrOffset, спасибо, но вероятность не сильно лучше при использовании приведенной вами формулой
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
#include <iostream>
#include <cstdlib>
 
using std::cout;
using std::cin;
using std::endl;
 
int main()
{
    int num = 0;
    unsigned long one = 0, zero = 0, N = 100;
    
    cout << "N = ";
    cin >> N;
    
    srand(0);
    
    for(unsigned long i = 0; i < N; i++)
    {
        num = rand()%2;
        if(num)
            one++;
        else
            zero++;
    }
        
    cout << "rand()%2 : P(1) = " << 1.0*one/N << ", P(0) = " << 1.0*zero/N << endl;
    
    srand(0);
    
    one = 0;
    zero = 0;
    
    for(unsigned long i = 0; i < N; i++)
    {
        num = (rand() / (RAND_MAX / 2 + 1));
        if(num)
            one++;
        else
            zero++;
    }
    
    cout << "(rand() / (RAND_MAX / 2 + 1)): P(1) = " << 1.0*one/N << ", P(0) = " << 1.0*zero/N << endl;
    
    return 0;
}
0
DrOffset
7517 / 4513 / 1025
Регистрация: 30.01.2014
Сообщений: 7,362
02.01.2017, 20:31 #11
Цитата Сообщение от cybeuser Посмотреть сообщение
вероятность не сильно лучше при использовании приведенной вами формулой
Никто и не обещал этого.
Задача была убрать полосы.

Для более качественного результата нужно менять гпсч.
1
cybeuser
55 / 105 / 43
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 20:31 #12
DrOffset, я вас понял, спасибо за ответы.
0
02.01.2017, 20:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.01.2017, 20:31
Привет! Вот еще темы с ответами:

Для распределения по нормальному закону подойдет функция rand? - PHP
Дано задание по php: Для выборки из 100 случайных величин, распределенных по нормальному закону, создать полигон и гистограмму частот....

Построить график плотности распределения полученного посредством GPSS - GPSS
Не могу справиться с поставленной задачей, в gpss не работал и азов не знаю, что-то рассказывали так поверхностно, что то вроде &quot; вот есть...

Вывести случайный совет из массива с помощью Rand - C#
namespace ConsoleApplication5 { class Program { static void Main(string args) { string str...

Неравномерность в импульсной характеристике фильтра - Цифровая обработка сигналов
Подскажите причину появления неравномерности в импульсной характеристике фильтра, сформированной по методу частотной выборки на основе...


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

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

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