Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
#1

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

02.01.2017, 18:56. Просмотров 812. Ответов 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() сделать генератор дробных чисел
srand(time(NULL)); rand()%1000; этот генератор генерирует целые числа, как...

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

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

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

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

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

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

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

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

Linear congruential generator

Вместо встроенного PRNG используйте что-либо получше, например Mersenne Twister
0
nefton
44 / 20 / 6
Регистрация: 28.02.2013
Сообщений: 193
02.01.2017, 19:17  [ТС] #6
версия студии
0
Миниатюры
Неравномерность распределения полученного с помощью rand()  
DrOffset
7590 / 4559 / 1105
Регистрация: 30.01.2014
Сообщений: 7,421
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
105 / 105 / 73
Регистрация: 18.11.2013
Сообщений: 289
02.01.2017, 19:57 #8
DrOffset, но ведь и так и так будет равномерное распределение, разве нет?

Добавлено через 10 минут
nefton, можно ли называть багом равномерность, используя генератор с равномерным распределением?
0
DrOffset
7590 / 4559 / 1105
Регистрация: 30.01.2014
Сообщений: 7,421
02.01.2017, 20:16 #9
Лучший ответ Сообщение было отмечено nefton как решение

Решение

Цитата Сообщение от cybeuser Посмотреть сообщение
но ведь и так и так будет равномерное распределение, разве нет?
Конечно нет.
Грубо обрезая диапазон [0, RAND_MAX] по модулю 2, мы его (равномерное распределение) теряем.
Вот неплохое объяснение: http://stackoverflow.com/a/10984975

Добавлено через 14 минут
Вообще, некорректность использования формулы rand() % N уже давно всем известна, странно называть это багом, когда такие вещи уже давно вынесены в FAQ; Например: http://c-faq.com/lib/randrange.html
3
cybeuser
105 / 105 / 73
Регистрация: 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
7590 / 4559 / 1105
Регистрация: 30.01.2014
Сообщений: 7,421
02.01.2017, 20:31 #11
Цитата Сообщение от cybeuser Посмотреть сообщение
вероятность не сильно лучше при использовании приведенной вами формулой
Никто и не обещал этого.
Задача была убрать полосы.

Для более качественного результата нужно менять гпсч.
1
cybeuser
105 / 105 / 73
Регистрация: 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

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

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

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


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

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

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