Liczby pseudolosowe. Generowanie sekwencji pseudolosowych Ustaw granice zakresu dla Rand()

Mamy ciąg liczb składający się z praktycznie niezależnych elementów, które spełniają zadany rozkład. Z reguły rozkład równomierny.

Liczby losowe można generować w programie Excel na różne sposoby. Rozważmy tylko najlepsze z nich.

Funkcja liczb losowych w programie Excel

  1. Funkcja LOS zwraca losową liczbę rzeczywistą o równomiernym rozkładzie. Będzie mniejsza niż 1, większa lub równa 0.
  2. Funkcja RANDBETWEEN zwraca losową liczbę całkowitą.

Przyjrzyjmy się ich zastosowaniu na przykładach.

Próbkowanie liczb losowych za pomocą RAND

Ta funkcja nie wymaga żadnych argumentów (RAND()).

Aby na przykład wygenerować losową liczbę rzeczywistą z zakresu od 1 do 5, użyj następującej formuły: =RANDA()*(5-1)+1.

Zwrócona liczba losowa jest rozłożona równomiernie w przedziale.

Za każdym razem, gdy arkusz jest obliczany lub gdy zmienia się wartość w dowolnej komórce arkusza, zwracana jest nowa liczba losowa. Jeśli chcesz zapisać wygenerowaną populację, możesz zastąpić formułę jej wartością.

  1. Kliknij komórkę z losową liczbą.
  2. Na pasku formuły wybierz formułę.
  3. Naciśnij klawisz F9. I WEJDŹ.

Sprawdźmy równomierność rozkładu liczb losowych z pierwszej próbki za pomocą histogramu rozkładu.


Zakres wartości pionowych to częstotliwość. Poziomo - „kieszenie”.



Funkcja RANDBETWEEN

Składnia funkcji RANDBETWEEN jest następująca (granica dolna; granica górna). Pierwszy argument musi być mniejszy niż drugi. W przeciwnym razie funkcja zgłosi błąd. Zakłada się, że granice są liczbami całkowitymi. Formuła odrzuca część ułamkową.

Przykład użycia funkcji:

Liczby losowe z dokładnością 0,1 i 0,01:

Jak zrobić generator liczb losowych w programie Excel

Stwórzmy generator liczb losowych, który generuje wartość z pewnego zakresu. Używamy formuły takiej jak: =INDEKS(A1:A10,INTEGER(RANDA()*10)+1).

Stwórzmy generator liczb losowych z zakresu od 0 do 100 w krokach co 10.

Musisz wybrać 2 losowe z listy wartości tekstowych. Korzystając z funkcji LOS, porównujemy wartości tekstowe z zakresu A1:A7 z liczbami losowymi.

Użyjmy funkcji INDEX, aby wybrać dwie losowe wartości tekstowe z oryginalnej listy.

Aby wybrać jedną losową wartość z listy, użyj następującej formuły: =INDEKS(A1:A7,RANDBETWEEN(1,COUNT(A1:A7))).

Generator liczb losowych o rozkładzie normalnym

Funkcje RAND i RANDBETWEEN generują liczby losowe o rozkładzie równomiernym. Dowolna wartość z takim samym prawdopodobieństwem może wpaść w dolną granicę żądanego zakresu i do górnej. Powoduje to ogromny spread od wartości docelowej.

Rozkład normalny oznacza, że ​​większość wygenerowanych liczb jest bliska wartości docelowej. Dostosujmy formułę RANDBETWEEN i utwórzmy tablicę danych o rozkładzie normalnym.

Koszt produktu X wynosi 100 rubli. Cała wyprodukowana partia ma rozkład normalny. Zmienna losowa również ma normalny rozkład prawdopodobieństwa.

W takich warunkach średnia wartość zakresu wynosi 100 rubli. Wygenerujmy tablicę i zbudujmy wykres o rozkładzie normalnym z odchyleniem standardowym 1,5 rubla.

Używamy funkcji: =NORMINV(RANDA();100;1,5).

Excel obliczył, które wartości mieściły się w zakresie prawdopodobieństwa. Ponieważ prawdopodobieństwo wytworzenia produktu o koszcie 100 rubli jest maksymalne, formuła częściej niż inne pokazuje wartości bliskie 100.

Przejdźmy do narysowania wykresu. Najpierw musisz utworzyć tabelę z kategoriami. W tym celu dzielimy tablicę na okresy:

Na podstawie uzyskanych danych będziemy mogli wygenerować diagram o rozkładzie normalnym. Oś wartości to liczba zmiennych w przedziale, oś kategorii to okresy.

Proszę zawiesić AdBlock na tej stronie.

Czasami może być konieczne wygenerowanie liczb losowych. Prosty przykład.

Przykład: ustalenie zwycięzcy w konkursie na repost.

Na liście znajdują się 53 osoby. Konieczne jest wybranie spośród nich zwycięzcy. Jeśli sam to wybierzesz, możesz zostać oskarżony o stronniczość. Decydujesz się więc napisać program. Będzie to działać w następujący sposób. Wpisujesz liczbę uczestników N, po czym program wyświetla jedną liczbę – numer zwycięzcy.

Wiesz już, jak zdobyć numer od gracza. Ale jak zmusić komputer do wymyślenia liczby losowej? W tej lekcji dowiesz się, jak to zrobić.

funkcja Rand().

Ta funkcja zwraca losową liczbę całkowitą z zakresu od zera do RAND_MAX. RAND_MAX to specjalna stała C przechowująca maksymalną wartość całkowitą, jaką może zwrócić funkcja Rand().

Funkcja Rand() jest zdefiniowana w pliku nagłówkowym stdlib.h. Dlatego jeśli chcesz używać Rand w swoim programie, nie zapomnij dołączyć tego pliku nagłówkowego. W tym pliku zdefiniowana jest także stała RAND_MAX. Możesz znaleźć ten plik na swoim komputerze i zobaczyć jego znaczenie.

Zobaczmy tę funkcję w akcji. Uruchommy następujący kod:

Lista 1.

#włączać // aby użyć funkcji printf #include // aby użyć funkcji Rand int main(void) ( /* wygeneruj pięć losowych liczb całkowitych */ printf("%d\n", Rand()); printf("%d\n", Rand()); printf („%d\n”, Rand()); printf(„%d\n”, Rand()); printf(„%d\n”, Rand());

Powinno to wyglądać mniej więcej tak.

Ryc.1 Pięć liczb losowych wygenerowanych przez funkcję Rand

Ale chcielibyśmy uzyskać liczby od 1 do 53, a nie wszystko z rzędu. Oto kilka sztuczek, które pomogą Ci ograniczyć funkcję Rand().

Ogranicz liczby losowe z góry.

Każdy, kto czekał w szkole na moment, w którym przyda się matematyka, niech się przygotuje. Nadeszła ta chwila. Aby ograniczyć liczby losowe z góry, możesz skorzystać z operacji obliczania reszty dzielenia, której nauczyłeś się na ostatniej lekcji. Prawdopodobnie wiesz, że reszta z dzielenia przez liczby K jest zawsze mniejsza niż liczba K. Na przykład dzielenie przez 4 może dać resztę 0, 1, 2 i 3. Dlatego jeśli chcesz ograniczyć liczby losowe z góry do liczby K, po prostu weź resztę dzielenia przez K. Lubię to:

Lista 2.

#włączać #włączać int main(void) ( /* generuje pięć losowych liczb całkowitych mniejszych niż 100 */ printf("%d\n", rand()%100); printf("%d\n", rand()%100); printf („%d\n”, rand()%100); printf(„%d\n”, rand()%100); printf(„%d\n”, rand()%100);


Ryc.2 Pięć liczb losowych mniejszych niż 100

Ogranicz liczby poniżej.

Funkcja Rand zwraca losowe liczby z przedziału. A co jeśli potrzebujemy tylko liczb większych niż M (na przykład 1000)? Co powinienem zrobić? To proste. Dodajmy po prostu naszą wartość M do wartości zwróconej przez funkcję Rand. Wtedy, jeśli funkcja zwróci 0, ostateczną odpowiedzią będzie M, jeśli 2394, to ostateczną odpowiedzią będzie M + 2394. Wydaje się, że dzięki tej akcji przesuwamy wszystkie liczby do przodu o M jednostek.

Ustaw górną i dolną granicę funkcji Rand.

Na przykład uzyskaj liczby od 80 do 100. Wygląda na to, że wystarczy połączyć dwie powyższe metody. Otrzymamy coś takiego:

Lista 3.

#włączać #włączać int main(void) ( /* generuje pięć losowych liczb całkowitych większych niż 80 i mniejszych niż 100 */ printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + Rand ()%100); printf("%d\n", 80 + Rand()%100); printf("%d\n", 80 + Rand()%100); 100);

Spróbuj uruchomić ten program. Zaskoczony?

Tak, ta metoda nie zadziała. Uruchommy ten program ręcznie i zobaczmy, czy popełniliśmy błąd. Załóżmy, że funkcja Rand() zwróciła liczbę 143. Reszta z dzielenia przez 100 wynosi 43. Wtedy 80 + 43 = 123. Zatem ta metoda nie działa. Podobny projekt pozwoli uzyskać liczby od 80 do 179.

Rozłóżmy nasze wyrażenie krok po kroku. Rand()%100 może zwracać liczby od 0 do 99 włącznie. Te. z segmentu.
Operacja + 80 przesuwa nasz segment 80 jednostek w prawo. Dostajemy.
Jak widać, nasz problem leży w prawej krawędzi segmentu, jest on przesunięty w prawo o 79 jednostek. To jest nasza pierwotna liczba 80 minus 1. Zróbmy porządek i cofnijmy prawą granicę: 80 + rand()%(100 - 80 + 1) . Wtedy wszystko powinno działać jak należy.

Ogólnie rzecz biorąc, jeśli chcemy uzyskać liczby z segmentu, musimy zastosować następującą konstrukcję:
A + Rand()%(B-A+1) .

Zgodnie z tą formułą przepiszemy nasz ostatni program:

Lista 4.

#włączać #włączać int main(void) ( /* generuje pięć losowych liczb całkowitych z segmentu */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("%d\n", 80 + Rand()%(100 - 79)); printf("%d\n", 80 + Rand()%21); printf("%d\n", 80 + printf()%21); "%d\n", 80 + rand()%21 )

Wynik:


Ryc.3 Losowe liczby z zakresu

Cóż, teraz możesz rozwiązać pierwotny problem lekcji. Wygeneruj liczbę z segmentu. Albo nie możesz?

Ale najpierw kilka bardziej przydatnych informacji. Uruchom ostatni program trzy razy z rzędu i zapisz wygenerowane przez niego liczby losowe. Czy zauważyłeś?

funkcja śrand().

Tak, za każdym razem pojawiają się te same identyczne liczby. „Taki sobie generator!” - mówisz. I nie będziesz do końca miał rację. Rzeczywiście, cały czas generowane są te same liczby. Możemy jednak na to wpłynąć, korzystając z funkcji srand(), która jest również zdefiniowana w pliku nagłówkowym stdlib.h. Inicjuje generator liczb losowych numerem początkowym.

Skompiluj i uruchom ten program kilka razy:

Lista 5.

#włączać #włączać int main(void) ( srand(2); /* generuje pięć losowych liczb całkowitych z segmentu */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("% d\n", 80 + Rand()%(100 - 79)); printf("%d\n", 80 + Rand()%21); printf("%d\n", 80 + Rand() %21); printf("%d\n", 80 + rand()%21);

Teraz zmień argument funkcji srand() na inną liczbę (mam nadzieję, że nie zapomniałeś, co to jest argument funkcji?), a następnie skompiluj i uruchom program ponownie. Kolejność liczb musi się zmienić. Gdy tylko zmienimy argument w funkcji srand, zmienia się także kolejność. Mało praktyczne, prawda? Aby zmienić kolejność, należy ponownie skompilować program. Oby tylko ten numer został tam wstawiony automatycznie.

I można to zrobić. Użyjmy na przykład funkcji time(), która jest zdefiniowana w pliku nagłówkowym time.h. Ta funkcja, jeśli jako argument zostanie przekazana wartość NULL, zwraca liczbę sekund, które upłynęły od 1 stycznia 1970 r. Oto jak to się robi.

Lista 6.

#włączać #włączać #włączać // aby użyć funkcji time() int main(void) ( srand(time(NULL)); /* wygeneruj pięć losowych liczb całkowitych z segmentu */ printf("%d\n", 80 + rand()%( 100 - 80 + 1)); printf("%d\n", 80 + rand()%(100 - 79)); printf("%d\n", 80 + rand()%21); \n", 80 + Rand()%21); printf("%d\n", 80 + Rand()%21); )

Możesz zapytać, co to jest NULL? Rozsądne pytanie. W międzyczasie opowiem Ci, czym jest to specjalne, zastrzeżone słowo. Mogę też powiedzieć, co oznacza wskaźnik zerowy, ale... Nie dostarcza to żadnych informacji, więc radzę w tej chwili o tym nie myśleć. I zapamiętaj to jako sprytną sztuczkę. Na przyszłych lekcjach przyjrzymy się tej kwestii bardziej szczegółowo.

W edukacyjnych problemach algorytmicznych dość powszechna jest potrzeba generowania losowych liczb całkowitych. Można je oczywiście otrzymać od użytkownika, jednak mogą pojawić się problemy z wypełnieniem tablicy 100 losowymi liczbami.

Z pomocą przychodzi nam standardowa funkcja biblioteczna języka C (nie C++) Rand().

int rand(void);

Generuje pseudolosową liczbę całkowitą z zakresu wartości od 0 do RAND_MAX. Ta ostatnia jest stałą, która zmienia się w zależności od implementacji języka, ale w większości przypadków wynosi 32767.
A co jeśli potrzebujemy losowych liczb od 0 do 9? Typowym wyjściem z tej sytuacji jest zastosowanie operacji dzielenia modulo.

Jeśli potrzebujemy liczb od 1 (nie 0) do 9, możemy dodać jedną...

Pomysł jest taki: generujemy losową liczbę od 0 do 8, a po dodaniu 1 zamienia się ona w losową liczbę od 1 do 9.

I na koniec najsmutniejsza rzecz.
Niestety funkcja Rand() generuje liczby pseudolosowe, tj. liczby, które wydają się losowe, ale w rzeczywistości są ciągiem wartości obliczonych za pomocą sprytnego algorytmu, który jako parametr przyjmuje tzw. ziarno. Te. Liczby wygenerowane przez funkcję Rand() będą zależeć od wartości ziarna w momencie jego wywołania. A ziarno jest zawsze ustawiane przez kompilator na wartość 1. Inaczej mówiąc, sekwencja liczb będzie pseudolosowa, ale zawsze taka sama.
A to nie jest to, czego potrzebujemy.

Funkcja srand() pomaga naprawić sytuację.

void srand(unsigned int ziarno);

Ustawia ziarno równe wartości parametru z jakim zostało wywołane. Kolejność liczb również będzie inna.

Ale problem pozostaje. Jak sprawić, żeby ziarno było losowe, bo wszystko od niego zależy?
Typowym wyjściem z tej sytuacji jest użycie funkcji time().

czas_t czas(timer_t*);

Jest również dziedziczony z języka C i wywołany ze wskaźnikiem zerowym jako parametrem zwraca liczbę sekund, które upłynęły od 1 stycznia 1970 r. Nie, to nie jest żart.

Teraz możemy przekazać wartość tej funkcji do funkcji srand() (która wykonuje niejawne rzutowanie) i otrzymamy wspaniałe losowe ziarno.
A liczby będą wspaniałe i niepowtarzalne.

Aby używać funkcji Rand() i srand(), musisz dołączyć plik nagłówkowy i użyć time() - plik .

Oto kompletny przykład.

#włączać
#włączać
#włączać

używając przestrzeni nazw std;

int główny()
{
cout<< "10 random numbers (1..100): " << endl;
srand(czas(NULL));
for(int i=0;i<10;i++) cout << rand() % 100 + 1 << " ";
cin.get();
zwróć 0;
}

Funkcja generująca liczby pseudolosowe ma prototyp w pliku biblioteki stdlib.h:

1
2
3
4
5
6

unsigned long int następny = 1;
int rand(void)
{
następny = następny * 1103515245;
return ((unsigned int) (next / 65536) * 2768);
}


Funkcja Rand() nie przyjmuje żadnych argumentów, ale działa na następnej zmiennej o zasięgu globalnym.

Jeśli chcesz wygenerować sekwencję w zakresie , wówczas stosuje się wzór:

Liczba = Rand()%(M2-M1+1) + M1;

Gdzie Numer– wygenerowany numer. M2-M1+1– pełny zakres reprezentacji liczb. M1– przesunięcie określonego zakresu względem 0; % - pozostała część podziału .

Na przykład, jeśli chcesz wygenerować sekwencję z zakresu [-10;10], to wywołanie funkcji będzie wyglądać

Liczba = Rand()%(10+10+1)-10

Liczba = rand()%(21)-10

W wyniku otrzymania reszty z dzielenia przez 21 otrzymujemy liczbę od 0 do 20. Odejmując od otrzymanej liczby 10 otrzymujemy liczbę z żądanego zakresu [-10;10].

Jednakże sekwencja wygenerowana przez funkcję Rand() będzie wyglądać tak samo przy każdym uruchomieniu programu.

Aby przy każdym uruchomieniu programu generować inną sekwencję należy zainicjować zmienną globalną next wartością inną niż 1. W tym celu należy skorzystać z funkcji
void srand(unsigned int ziarno)
( następny = ziarno; )

Aby mieć pewność, że inicjalizacja next będzie inna przy każdym uruchomieniu programu, jako argument początkowy najczęściej używany jest bieżący czas.

Przykład Wypełnij tablicę składającą się z 20 elementów liczbami losowymi z zakresu od 0 do 99.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#włączać
#włączać
#włączać
#zdefiniuj ROZMIAR 20
int główna() (
int a;
srand(czas(NULL ));
for (int i = 0; tj {
a[i] = rand() % 100;
printf("%d ", a[i]);
}
getchar();
zwróć 0;
}


Wynik wykonania

Często pojawia się zadanie ułożenia istniejącego zestawu wartości w losowej kolejności. W tym celu wykorzystuje się także generator liczb pseudolosowych. Spowoduje to utworzenie tablicy i wypełnienie jej wartościami.
Sama procedura mieszania jest następująca. Losowo generowane są dwie wartości indeksów tablicy, a wartości elementów z uzyskanymi indeksami są zamieniane. Procedurę powtarza się co najmniej N razy, gdzie N jest liczbą elementów tablicy.
Jako przykład rozważ przetasowanie 20 wartości (od 1 do 20) i powtórzenie procedury 20 razy.

Implementacja w 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

#włączać
#włączać
#włączać
#zdefiniuj ROZMIAR 20
int główna() (
int a;
srand(czas(NULL ));

for (int i = 0; tj< SIZE; i++)
{
a[i] = ja + 1;
printf("%2d ", a[i]);
}
for (int i = 0; tj< SIZE; i++)
{
// Wygeneruj losowo dwa indeksy elementów
int ind1 = rand() % 20;
int ind2 = rand() % 20;
// i zamień elementy z tymi indeksami
int temperatura = a;
a = a;
a = temperatura;
}
printf("\n" );

for (int i = 0; tj< SIZE; i++)
printf("%2d ", a[i]);
getchar();
zwróć 0;
}


Wynik wykonania


Często pojawia się zadanie losowego wybierania wcześniej określonych elementów tablicy. Ponadto należy zadbać o brak powtórzeń w doborze tych elementów.
Algorytm tego wyboru jest następujący:

  • Losowo wybieramy indeks elementu tablicy
  • Jeżeli został już wybrany element o tym samym indeksie, przesuwaj się w prawo, aż dotrzemy do kolejnego niezaznaczonego elementu. Jednocześnie dbamy o to, aby „ruch w prawo” nie wykraczał poza granice szyku. Jeżeli zostanie wykryte przekroczenie zakresu tablicy, przeglądanie elementów tablicy rozpoczynamy od początku.
  • Wybór elementu
  • Naprawianie wybranego elementu
  • Powtórz te kroki dla wszystkich pozostałych elementów

Implementacje w C
W efekcie otrzymujemy nową tablicę b, utworzoną poprzez losowy wybór elementów tablicy a.

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

#włączać
#włączać
#włączać
#zdefiniuj ROZMIAR 20
int główna() (
int a;
int b; // wynikowa tablica
srand(czas(NULL ));
// Wypełnij tablicę kolejnymi wartościami od 1 do 20
for (int i = 0; tj< SIZE; i++)
{
a[i] = ja + 1;
printf("%2d ", a[i]);
}

for (int i = 0; tj< SIZE; i++)
{
int ind = rand() % 20; // wybierz dowolny indeks
podczas gdy (a == -1) // gdy element jest „wybrany”
{
ind++; //przesuń się w prawo
ind %= 20; // jeśli dotrzemy do prawej granicy, wróć do początku
}
b[i] = a; // napisz kolejny element tablicy b
a = -1; // zaznacz element tablicy a jako „wybrany”
}
printf("\n" );
// Wyprowadź wynikową tablicę
for (int i = 0; tj< SIZE; i++)
printf("%2d ", b[i]);
getchar();
zwróć 0;
}


Wynik wykonania

Tagi: C losowe, C liczby losowe, generowanie liczb losowych, RNG, liczby pseudolosowe, metoda Monte Carlo

Liczby pseudolosowe

Generowanie liczb pseudolosowych jest złożonym problemem matematycznym. Celem tego artykułu nie jest omówienie tego tematu. W dalszej części pojęcie „liczby losowej” będzie oznaczać liczbę pseudolosową, chyba że określono inaczej.

Wszędzie można spotkać przykłady użycia liczb losowych. Liczby pseudolosowe są wykorzystywane w projektowaniu i grafice, do generowania poziomów w grach komputerowych i do symulacji sztucznej inteligencji. W algorytmach matematycznych wykorzystuje się zbiory liczb losowych (patrz metody Monte Carlo).

Oczywiście problemu generowania liczb losowych nie da się rozwiązać na klasycznym procesorze, gdyż działanie komputera z definicji jest deterministyczne. Można jednak generować bardzo długie zbiory liczb, tak że ich rozkład ma takie same właściwości jak zbiory liczb prawdziwie losowych.

Ważne jest, aby rozwiązać konkretny problem, aby wybrać odpowiedni generator lub przynajmniej poznać jego właściwości. Przykładowo modelując proces fizyczny można uzyskać zupełnie inne i często błędne wyniki, w zależności od wyboru generatora liczb losowych.

Spójrzmy na standardowy generator.

#włączać #włączać #włączać int main() ( int i, r; srand(42); for (i = 0; i< 10; i++) { r = rand(); printf("%d\n", r); } _getch(); return 0; }

Najpierw należy zainicjalizować generator liczb losowych (RNG lub RNG – generator liczb losowych), ustawić ziarno, na podstawie którego w przyszłości odbędzie się generowanie. Ważne jest, aby dla tej samej wartości początkowej generator zwracał te same liczby.

Srand(42);

Przypisz zmiennej r losową wartość

R = rand();

Wartość będzie z zakresu od 0 do RAND_MAX.

Aby przy następnym uruchomieniu otrzymać nowy zestaw liczb, należy za każdym razem inicjować generator innymi wartościami. Na przykład możesz użyć czasu systemowego:

Srand(czas(NULL));

Srand(_getpid());

Funkcja getpid biblioteki Process.h zwraca identyfikator procesu (można także użyć getpid, wersji tej funkcji innej niż POSIX).

Centralne twierdzenie graniczne

Bardzo ważne jest natychmiastowe przypomnienie lub wprowadzenie centralnego twierdzenia granicznego. Definicja nieformalna: rozkład sumy słabo zależnych zmiennych losowych ma tendencję do normalnego. Wyjaśnienie w kształcie palca: jeśli dodasz kilka zmiennych losowych, niezależnie od ich rozkładu, rozkład sumy będzie normalny. Często można zobaczyć taki kod

#włączać #włączać #włączać int main() ( int i, r, r1, r2, r3; srand(czas(NULL)); r1 = rand(); r2 = rand(); r3 = rand(); r = (r1 + r2 + r3 ) / 3; printf("%d", r);

Generowanie liczb losowych w zadanym przedziale

Najpierw otrzymujemy losową liczbę od zera do jednego:

Stała liczba zmiennoprzecinkowa RAND_MAX_F = RAND_MAX; float get_rand() (zwróć Rand() / RAND_MAX_F; )

Aby otrzymać liczbę z zakresu od zera do N, należy pomnożyć N przez liczbę losową od zera do jednego. Aby otrzymać liczbę losową od M do N, przesuwamy wynikową liczbę o M.

Float get_rand_range(const float min, const float max) ( return get_rand() * (max - min) + min; )

Aby otrzymać liczbę całkowitą, resztę dzielenia obliczamy przez długość przedziału. Ale pozostała część dzielenia zwróci liczbę o jeden mniejszą niż nasz przedział, więc zwiększamy go o jeden:

Int get_rand_range_int(const int min, const int max) ( return rand() % (max - min + 1) + min; )

Przykład wykorzystania liczb losowych do obliczenia całki. Załóżmy, że mamy gładką funkcję jednej zmiennej. Ograniczmy to do kwadratu od a do b i od 0 do pewnego punktu, który jest oczywiście większy od naszej funkcji.

Losowo będziemy rzucać punkty na nasz kwadrat. Jeżeli leżą powyżej funkcji (na rysunku zielone krzyżyki), to przypiszemy je do pierwszej grupy A, jeżeli poniżej funkcji (na rysunku na czerwono), to przypiszemy je do drugiej grupy B. położenie punktów jest losowe i rozłożone równomiernie (ponieważ generator standardowo daje rozkład równomierny. Swoją drogą ten prosty przykład już pokazuje, jak ważne jest poznanie właściwości RNG). Wtedy stosunek czerwonych kropek do całkowitej liczby kropek będzie równy stosunkowi pola pod wykresem do całkowitej powierzchni. A całkowita powierzchnia to kwadrat (b-a) przez q.

Src="/images/c_random_integral.png" alt=" Wszystko, co losowo wypada powyżej naszej funkcji, jest zielone, wszystko poniżej jest czerwone.
Stosunek koloru zielonego do czerwonego będzie równy stosunkowi obszaru nad wykresem do obszaru pod wykresem."> Всё, что случайно попадает выше нашей функции - зелёное, всё что ниже - красное. !}
Stosunek koloru zielonego do czerwonego będzie równy stosunkowi obszaru nad wykresem do obszaru pod wykresem.

Zastosujmy nasze obliczenia - znajdź całkę funkcji x^2 na przedziale od 0 do dwa na dwa sposoby.

#włączać #włączać #włączać #włączać #włączać stała liczba zmiennoprzecinkowa RAND_MAX_F = RAND_MAX; float get_rand() ( return rand() / RAND_MAX_F; ) float get_rand_range(const float min, const float max) ( return get_rand() * (max - min) + min; ) #define RUNDY 1000 float fun(float x) ( return x * x; ) float kwadrat_kwadrat(float a, float b, float q) ( float h = (b - a) / (float)ROUNDS; float suma = 0; for (; a< b; a += h) { sum += fun(a) * h; } return sum; } float rand_square(float a, float b, float q) { float res; float x, y; int i; int lower = 0; float ratio; float square; srand(time(NULL)); for (i = 0; i < ROUNDS; i++) { x = get_rand_range(a, b); y = get_rand_range(0, q); res = fun(x); if (res >y) (niższy++; ) ) stosunek = (float)niższy / (float)RUNDY; kwadrat = (b - a) * q * stosunek; powrót do kwadratu; ) int main() ( float abs_ans = 2,66667f; float sr = rand_square(0, 2, 4); float ss = kwadrat_kwadrat(0, 2, 4); printf("Zaokrąglenia = %d\n", RUNDY); printf("Sa = %.5f\n", abs_ans); printf("Sr = %.5f\n", sr); printf("Ss = %.5f\n", ss); ", fabs(sr - abs_ans)); printf("ds = %.5f\n", fabs(ss - abs_ans)); _getch(); return 0; )

Pobaw się wartością ROUNDS, zmień ją i zobacz, jak zmienia się dokładność obliczeń.

Generowanie prawdziwych liczb losowych

Do generowania rzeczywistych liczb losowych wykorzystuje się generatory bazujące na losowych procesach fizycznych. Na przykład o szumie termicznym, o liczeniu liczby rozszczepień substancji radioaktywnej, o hałasie atmosferycznym itp. Wadą takich generatorów jest ich niska prędkość robocza (liczba generowanych liczb na sekundę); oczywiście takie generatory są zwykle osobnym urządzeniem.