Главная » Статьи » Програмування » C [ Добавить статью ]

RUS Уроки по программированию на языке С (Генератор случайных чисел)

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

    В прошлом уроке мы с вами познакомились с таким понятием как массив и научились заполнять его значениями. Но все наши значения мы вписывали сами, то есть заранее знали какими они будут. Такой способ заполнения переменных и массивов ограничивает возможности программы. Невозможно создать нечто, обладающее искуственным интеллектом, если нет способа получать данные не зависящие от пользователя. Что же делать, если нам необходимы значения, выбранные случайным образом?

    Использование функции rand.

    В языке С существует возможность сгенерировать случайное число. Для этой операции используется функция под названием rand(). Эта функция находиться в библиотечном файле - stdlib.h, следовательно для ее работы необходимо этот файл подключить с помощью диррективы #include. На место вызова rand() в программе, подставится случайное число в диапазоне от 0 до 32767. Рассмотрим простой пример:

    #include<iostream>
    #include<stdlib.h>// в этом файле содержится функция rand
    
    using namespace std;
    void main()
    { 
     int a;
     //генерация случайного числа и запись его в переменную a
     a=rand();
     cout<<a<<"\n";
    
     //повторная генерация случайного числа и запись его в переменную a
     a=rand();
     cout<<a<<"\n";
    }
    
    

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


    Запустите еще раз. И, снова - таже картина. Выходит, случайные числа - не случайны, кроме того они еще и повторяются от запуска к запуску. Не смотря на несправедливость этого утверждения - это так, и, вполне понятно, почему. Если вы подойдете к любому человеку и на улице и попросите назвать произвольное целое число, этот человек несомненно назовет именно случайное число. И то - не факт. Возможно, прохожий посмотрит на вывеску или на часы и извлечет это число из увиденного. Компьютер, в отличии от живого существа, не способен на ассоциативное мышление, поэтому функция rand() не получает число из воздуха, а работает, используя в качестве начальной точки – точку определенную при написании алгоритма генератора случайного числа, то есть некое постоянное число. Другими словами, опираясь на эту точку, при разных вызовах программы эта функция генерирует одно и то же число, в чём мы уже успели убедиться. Из этого можно сделать вывод: Для того, чтобы rand() при разных вызовах программы выдавал разные числа необходимо изменить начальную точку генерации.

    Использование функции srand.

    Местоположение функции - библиотека stdlib.h.

    Функция srand устанавливает начальную точку для генерации случайных чисел и обладает следующим синтаксисом:

    void srand(unsigned int start)

    Параметр start, который принимает функция, и есть - новая точка для генерации случайного числа. Давайте подумаем, какое же число вписать на место этого параметра. Целочисленный литерал или переменная, значение которой опредленно в момент написания программы - не подходят. Передав их на место отправной точки мы непременно изменим ее, но не сделаем динамической. И, числа будут генерироваться другие, но все еще одинаковые при каждом запуске.

    Пример с литералом, в качестве отправной точки.
    #include<iostream>
    #include<stdlib.h>// в этом файле содержатся функции rand и srand
    
    using namespace std;
    void main()
    {
     srand(5); 
     int a;
     //генерация случайного числа и запись его в переменную a
     a=rand();
     cout<<a<<"\n";
    }
    
    Пример с переменной, в качестве отправной точки.
    #include<iostream>
    #include<stdlib.h>// в этом файле содержатся функции rand и srand
    
    using namespace std;
    void main()
    {
     int start=25;
     srand(start); 
     int a;
     //генерация случайного числа и запись его в переменную a
     a=rand();
     cout<<a<<"\n";
    }
    

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

    Использование функции time.

    Местоположение функции - библиотека time.h.

    У функции time есть несколько предназначений и подробно разбирать мы ее не будем. Возьмем только то, что необходимо нам для работы. А, именно, если функцию time вызвать с параметром NULL, то на место своего вызова в программе, эта функция вернет количество миллисекунд прошедших с 1 января 1970 года. Согласитесь, что эта величина каждый раз будет разной. А, это - как раз то, что мы искали. "Соберем" полученную информацию в единое целое и получится:

    srand(time(NULL));
    

    Функция srand устанавливает в качестве стартовой точки число, представляющее собой количество, миллисекунд прошедших с 1 января 1970 года. Попробуем:

    #include<iostream>
    #include<stdlib.h>// в этом файле содержатся функции rand и srand
    #include<time.h>// в этом файле содержится функция time
    
    using namespace std;
    void main()
    {
     srand(time(NULL));
     int a;
     //генерация случайного числа и запись его в переменную a
     a=rand();
     cout<<a<<"\n";
    }
    

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

    Установка диапазона для генератора.

    Числа, которые получаются путем вызова функции rand, находятся в диапазоне от 0 до 32767. Но, ведь нам не всегда требуется такой масштабный разброс данных. Что делать, если необходимо генерировать числа от 0 до 10 или от 0 до 100 и так далее?! На помощь, в таких случаях, приходит старое, доброе - деление по модулю.

    Возьмем для примера произвольное число - 23. Согласитесь, что какое бы число вы не разделили на 23 по модулю, вы получите либо 0 (если остатка нет), либо остаток в диапазоне от 1 до 22. Этим свойством мы и воспользуемся, разделив сгенерированное случайное число по модулю:

    int a=rand()%23;
    

    На основании этого правила можно вывести формулу:

    ЧИСЛО В ДИАПАЗОНЕ ОТ НУЛЯ ДО Х:
    
     rand() % X
    
    

    Но, диапазон не всегда начинается с нуля. Пусть нам необходим диапазон от 11 до 16. Все просто. Необходимо сгенерировать числа от 0 до 5 (разница между 16 и 11), а потом "сдвинуть" полученный результат на 11 единиц.

    int a=rand()%5+11;
    

    И, на основании уже модифицированного правила можно вывести формулу:

    ЧИСЛО В ДИАПАЗОНЕ ОТ Y ДО Х:
    
     rand() % (X-Y) + Y
    
    

Категория: C | Добавил: DEN-SHP (05.11.2012)
Просмотров: 1583 | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]