Serwis Edukacyjny w I-LO w Tarnowie ![]() Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2025 mgr Jerzy Wałaszek |
SPIS TREŚCI |
Liczba losowa (ang. random number) jest liczbą r należącą do pewnego zbioru
wartości
Problem z otrzymaniem liczb losowych wynika stąd, iż komputer jest maszyną, której operacje są ściśle określone i nie ma możliwości wygenerowania liczby o nieokreślonej wartości. Gdy człowiek dokonuje rzutu kostką, nie wie co wypadnie. Taka sama operacja na komputerze wymagałaby działania, którego wynik jest nieprzewidywalny – żadna z operacji wykonywanych przez procesor nie posiada takiej cechy (o ile procesor jest sprawny). Problem starano się rozwiązać wykorzystując zewnętrzne źródła sygnałów losowych (np. generatory białego szumu ), jednakże w tego typu urządzenia nie są standardowo wyposażano komputery osobiste – należałoby wspomnieć o próbach wykorzystania szumów kart dźwiękowych, jednakże system ten nie rozpowszechnił się z prostej przyczyny – różne karty dźwiękowe szumią różnie, a te z górnej półki nie szumią praktycznie wcale.
Obecnie możemy skorzystać z serwisów internetowych, które udostępniają nam liczby losowe z wybranego zakresu, na przykład witryna:
W witrynie dostępny jest prosty interfejs generatora liczb losowych:
W okienku ustawiamy pożądany zakres liczb losowych, po czym klikamy w przycisk Generate. Wylosowana liczba losowa jest wyświetlana w polu Result. Tego typu rozwiązanie pozwala nam losować pojedyncze liczby.
Liczby losowe używane są powszechnie przy programowaniu komputerów – wszelkiego rodzaju gry losowe, symulacje różnych procesów losowych, statystycznych, testowanie algorytmów dla losowych zestawów danych itp. Ponieważ nie możemy w prosty sposób mieć prawdziwych liczb losowych, musimy się zadowolić ich sztucznym odpowiednikiem – liczbami pseudolosowymi (ang. pseudorandom numbers). Liczby pseudolosowe wyglądają jak losowe, lecz tworzy się je algorytmicznie. Oznacza to, iż znając wzór generacyjny oraz kilka kolejnych liczb pseudolosowych możemy bez problemu wygenerować wszystkie dalsze – tej cechy nie posiadają prawdziwe liczby losowe, w przeciwnym razie totolotek straciłby sens a kasyna zbankrutowałyby.
Do rozwiązania problemu generacji liczb pseudolosowych opracowano specjalne funkcje modularne zwane liniowymi generatorami kongruencyjnymi liczb pseudolosowych (ang. pseudorandom number linear congruential generator – w skrócie LCG) o następującej postaci:
Xn
= (a×Xn-1+c)%m |
|
Xn | – n-ta liczba pseudolosowa |
Xn-1 | – poprzednia liczba pseudolosowa |
a | – mnożnik |
c | – przyrost |
m | – moduł |
Ze wzoru wynika, iż kolejna liczba pseudolosowa Xn powstaje z poprzedniej Xn-1. Liczby te tworzą zatem ściśle określony ciąg kolejno następujących po sobie wartości.
Drugą cechą charakterystyczną jest to, iż liczba pseudolosowa
Xn jest resztą z dzielenia przez moduł
m. Skoro tak,
to może tylko przyjmować wartości
Jeśli współczynniki a, c i m są źle dobrane, to okres powtarzania może być krótszy niż m.
Rozróżniamy dwa podstawowe rodzaje generatorów LCG:
Addytywny LCG: | Xn = (aXn-1+c)%m |
Multiplikatywny LCG: | Xn = aXn-1%m |
Podstawowa różnica pomiędzy nimi jest taka, iż generator
addytywny LCG może generować liczby pseudolosowe z zakresu
Określamy zakres liczb pseudolosowych 0...Xmax
(dla LCG multiplikatywnego jest to 1...Xmax).
Moduł
m = Xmax+1
Przyrost c musi być względnie pierwszy z modułem m. Możemy m rozłożyć na czynniki pierwsze i dla c wybieramy czynniki nie występujące w m. Możemy również generować pseudolosowe c i sprawdzać, czy spełnia warunek:
NWD(c, m) = 1
Mnożnik dobieramy wykorzystując regułę, iż wyrażenie a-1 jest podzielne przez każdy czynnik pierwszy modułu
m. Jeśli moduł
m dzieli się przez 4, to
Zaprojektować addytywny generator LCG generujący liczby pseudolosowe w przedziale od 0 do 11.
Z warunków zadania mamy:
Xmax = 11 m = Xmax + 1 = 11 + 1 = 12
Przyrost c musi być względnie pierwszy z m. Moduł m rozkładamy na iloczyn czynników pierwszych:
m = 2 × 2 × 3
Na przyrost c możemy wybrać dowolną liczbę nie posiadającą czynników 2 i 3. Na przykład może to być:
c = 7
Wyrażenie a-1 musi być podzielne przez 4 i 3.
a - 1 = 4 × 3 = 12 a = 12 + 1 = 13
Otrzymujemy następujący wzór generatora LCG:
Xn = (13×Xn-1+7)%12 → LCG(12,13,7)
Ponieważ wzór ten pozwala obliczyć kolejną liczbę pseudolosową Xn z liczby poprzedniej Xn-1, musimy określić wartość startową X0, od której rozpocznie się generacja liczb pseudolosowych. Wartość tę nazywamy ziarnem pseudolosowym (ang. pseudorandom seed). Ziarno wpływa na miejsce w pierścieniu liczb pseudolosowych, od którego rozpocznie się generacja następnych liczb.
Przyjmijmy X0 = 0 i policzmy wszystkie kolejne liczby pseudolosowe, które tworzy nasz generator LCG:
X1 = 13 × | 0 + 7 mod 12 = | 7 mod 12 = | 7 | |
X2 = 13 × | 7 + 7 mod 12 = | 98 mod 12 = | 2 | |
X3 = 13 × | 2 + 7 mod 12 = | 33 mod 12 = | 9 | |
X4 = 13 × | 9 + 7 mod 12 = | 124 mod 12 = | 4 | |
X5 = 13 × | 4 + 7 mod 12 = | 59 mod 12 = | 11 | |
X6 = 13 × | 11 + 7 mod 12 = | 150 mod 12 = | 6 | |
X7 = 13 × | 6 + 7 mod 12 = | 85 mod 12 = | 1 | |
X8 = 13 × | 1 + 7 mod 12 = | 20 mod 12 = | 8 | |
X9 = 13 × | 8 + 7 mod 12 = | 111 mod 12 = | 3 | |
X10 = 13 × | 3 + 7 mod 12 = | 46 mod 12 = | 10 | |
X11 = 13 × | 10 + 7 mod 12 = | 137 mod 12 = | 5 | |
X12 = 13 × | 5 + 7 mod 12 = | 72 mod 12 = | 0 | |
X13 = 13 × | 0 + 7 mod 12 = | 7 mod 12 = | 7 | = X1 – ciąg zaczyna się powtarzać |
X14 = 13 × | 7 + 7 mod 12 = | 98 mod 12 = | 2 | = X2 |
Dla X0 = 0 otrzymaliśmy ciąg liczb pseudolosowych: 7 2 9 4 11 6 1 8 3 10 5 0 7 2 9 4 ...
Jeśli przyjmiemy inną wartość za X0, to otrzymamy ten sam ciąg, lecz startujący od innego punktu:
Dla X0 = 1 mamy : 8 3 10 5 0 7 2 9 4 11 6 1 ... Dla X0 = 2 mamy : 9 4 11 6 1 8 3 10 5 0 7 2 ... Dla X0 = 3 mamy : 10 5 0 7 2 9 4 11 6 1 8 3 ...
Następstwo kolejnych liczb pseudolosowych jest zawsze takie samo – np. po liczbie 3 zawsze wystąpi liczba 10.
Z powyższych rozważań można wyciągnąć wniosek, iż każdy generator LCG da się jednoznacznie scharakteryzować czwórką parametrów:
LCG(m,a,c,X0) m – moduł a – mnożnik c – przyrost X0 – ziarno
Python# Generator pseudolosowy #----------------------- # współczynniki m = 12 a = 13 c = 7 # ziarno pseudolosowe x0 = 0 for i in range(m): x0 = (a * x0 + c) % m print(x0) |
W praktycznych realizacjach dąży się do dużych okresów generatora LCG – wtedy liczby pseudolosowe powtarzają się dopiero po wielu miliardach przebiegów. Jako przykład niech posłuży poniższy generator LCG zaproponowany przez prof. D. Knutha:
LCG(34359738368, 3141592653, 2718281829, Xo)
Język Python posiada wbudowany moduł generacji liczb pseudolosowych o nazwie random. Aby go uaktywnić, na początku programu umieść polecenie:
Python# Liczby pseudolosowe #-------------------- import random ... |
Moduł random posiada wiele wbudowanych funkcji, które obsługują liczby pseudolosowe. Funkcje te wywołujemy poprzez nazwę random:
random.funkcja(parametry)
Funkcja generuje całkowitą liczbę pseudolosową z podanego
zakresu. Parametr zakres posiada takie
samo znaczenie jak w funkcji
Generuje całkowitą liczbę pseudolosową z zakresu od 0 do
Python# Liczby pseudolosowe #-------------------- import random # 9 rzutów kostką for i in range(9): wynik = random.randrange(1,7) print("Rzut nr",i+1,":",wynik) |
Generuje całkowitą liczbę pseudolosową z zakresu od
Python# Liczby pseudolosowe #-------------------- import random # 9 rzutów kostką for i in range(9): wynik = random.randint(1,6) print("Rzut nr",i+1,":",wynik) |
Generuje rzeczywistą liczbę pseudolosową
Python# Liczby pseudolosowe #-------------------- import random for i in range(10): print(random.random()) |
Aby otrzymać rzeczywistą liczbę pseudolosową z zakresu
x = a + random.random * (b - a)
Python# Liczby pseudolosowe #-------------------- import random x = input("Wpisz dwie liczby: ").split() a = float(x[0]) b = float(x[1]) for i in range(10): print(a + random.random() * (b - a)) |
Python# Tablica pseudolosowa #--------------------- import random # Tworzymy pustą tablicę/listę t = [] # Dodajemy 100 elementów for i in range(100): t.append(random.randint(10,99)) print(t) |
Python# Tablica pseudolosowa #--------------------- import random # Tworzymy 100 elementową tablicę/listę t = [0] * 100 # Zmieniamy elementy for i in range(100): t[i] = random.randint(10,99) print(t) |
Python# Tablica pseudolosowa #--------------------- import random # Tworzymy 100 elementową tablicę/listę t = [random.randint(10,99) for i in range(100)] print(t) |
Sposób 3 wymaga wyjaśnienia. Tutaj pętla for jest wykorzystana bezpośrednio do definiowania kolejnych elementów tablicy listy. Składnia jest następująca:
nazwa = [wyrażenie for i in range(zakres)]
Kolejne obiegi pętli for powodują wyliczenie wartości wyrażenia i przypisanie jej do kolejnych elementów tablicy. Na przykład potrzebujemy tablicy ze 100 kolejnymi liczbami parzystymi:
Python# Tworzymy 100 elementową tablicę/listę t = [2 * i for i in range(100)] print(t) |
W przypadku tablicy pseudolosowej każdy obieg pętli for powoduje obliczenie wyrażenia random.randint(10,99). Wynikiem jest liczba pseudolosowa od 10 do 99. Liczba ta zostanie przypisana kolejnemu elementowi tworzonej tablicy listy. Elementów powstanie tyle, ile razy wykona się pętla for. W wyrażeniu można korzystać z wartości zmiennej pętli for (tutaj i).
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2025 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.