İnformatikada dövrün tapılması iterativ funksiyalar ardıcıllığında dövrün tapılması üçün alqoritmik problemdir (alqoritmdir).
Sonlu çoxluğunun özünə uyğun gələn, hər hansı bir
funksiyası üçün, və eyni zamanda
çoxluğundan olan
başlanğıc nöqtəsi üçün iterativ funksiyalar ardıcıllığı aşağıdakı kimidir:
Nəticə etibarilə burada funksiyanın eyni qiyməti aldığı cütlük olmalıdır, yəni elə bir və
cütlüyü olmalıdır ki,
şərti ödənmiş olsun. Bu baş verən andan ardıcıllıq dövri olaraq
və
aralığında eyni ardıcıllığı təkrarlayacaqdır. Dövrün tapılması məsələsi
və
-a görə
və
qiymətlərinin tapılmasıdır.
Bu məsələnin həlli üçün müxtəlif alqoritmlər mövcuddur. Məsələn, Floydun "bağa və dovşan alqoritmi" iki göstəricinin müxtəlif sürətlərlə hərəkət etdirilməsi və onlarn hansısa bir nöqtədə rastlaşmasına əsaslanır. Brentin alqoritmi isə eksponensial axtarış üsuluna əsaslanıb. Hər iki alqoritm iki göstəricidən istifadə edir. Yaddaşı daha çox istismar etməklə hesablamaları bir qədər azaldan digər müxtəlif alqoritmlər də mövcuddur.
Dövrün tapılması alqoritminin tətbiqi müxtəlifdir, nümunə olaraq psevdo-təsadüfi ədədlər generatoru, kriptoqrafik həş funksiyalar, ədədi üsullar üçün alqoritmlər, kompüter proqramlarında və konfiqurasiyalarında sonsuz dövrlərin tapılması və s.
Şəkildə çoxluğunun özünə uyğun olan funksiyası verilmişdir. Əgər nöqtəsindən başlayaraq ardıcıl olaraq funksiyasını tətbiq etsək aşağıdakı qiymətlər ardıcıllığını alarıq.
Burada 6, 3, 1 dövrdür.
Fərz edək ki, sonlu çoxluqdur, isə çoxluğundan özünə olan hər hansı funksiyadır. Burada çoxluğundan olan bir elementdir. İxtiyari i > 0 üçün xi = f(xi − 1) qəbul edək.
Fərz edək ki, elementi elementlər ardıcıllığında sonsuz olaraq təkrar olunur və burada ən kiçik indeks, (dövrün uzunluğu) isə ən kiçik müsbət ədəddir ki, bərabərliyini doğru edir. Dövrün tapılması məsələsi və ədədlərini tapmaqdan ibarətdir.[1]
Python proqramlaşdırma dilində kodu:
def floyd(f, x0):
# Alqoritmin əsas addımı: x_i = x_2i təkrarlanmasının tapılması.
# Dovşan bağadan iki dəfə daha sürətli hərəkət edir və
# onlar arasında məsafə hər addımda 1 vahid artır.
# Bir vaxt onlar hər ikisi dövrün daxilində olacaqlar,
# və onlar arasında məsafə λ ədədinə bölünən olacaq.
tortoise = f(x0) # f(x0) qiyməti x0-dan sonrakı element olacaq.
hare = f(f(x0))
while tortoise != hare:
tortoise = f(tortoise)
hare = f(f(hare))
# Bu anda bağanın mövqeyi, ν, (hansı ki, həm də başa ilə dovşan
# arasında məsafəyə bərabərdir) λ dövrünə bölünür.
# Dovşan dövrün daxilində bir addım olmaqla hərəkət edir,
# başa isə yenidən x0 nöqtəsindən başlayaraq dövrə tərəf hərəkət edir.
# intersect at the beginning of the circle. Onlar arasında məsafə
# sabit olaraq 2ν, və λ-ya bölünən olduğu üçün,
# bağa μ mövqeyinə çatan kimi görüşürlər.
# μ görüş yerinin tapılması
mu = 0
tortoise = x0
while tortoise != hare:
tortoise = f(tortoise)
hare = f(hare) # Dovşan və bağa eyni sürətlə hərəkət edirlər
mu += 1
# x_μ-dən başlayaraq ən qısa dövrün tapılması
# Dovşan bir addım hərəkət etməkdədir, bağa isə durub.
# λ tapılana qədər lam dəyişəni bir vahid artırılır
lam = 1
hare = f(tortoise)
while tortoise != hare:
hare = f(hare)
lam += 1
return lam, mu
Python proqramlaşdırma dilində kodu:
def brent(f, x0):
# əsas addım: 2 ədədinin qüvvətinin tapılması
power = lam = 1
tortoise = x0
hare = f(x0) # f(x0) - x0-dan sonrakı element/bənd.
while tortoise != hare:
if power == lam: # 2-nin yeni qüvvəti?
tortoise = hare
power *= 2
lam = 0
hare = f(hare)
lam += 1
# λ uzunluqlu dövrün başlanğıc nöqtəsi
mu = 0
tortoise = hare = x0
for i in range(lam):
# range(lam) 0, 1, ... , lam-1 qiymətlərindən ibarət siyahı hazırlanır
hare = f(hare)
# Hazırda dovşan və bağa arasında məsafə λ olur.
# Daha sonra dovşan və bağa rastlaşana qədər eyni sürətlə hərəkət edirlər
while tortoise != hare:
tortoise = f(tortoise)
hare = f(hare)
mu += 1
return lam, mu
Dövrün tapılması məsələsinin bir çox praktiki tətbiqi vardır.
*print-circle*
dəyişəni altında dövrü aşkar edir və yığcam şəkildə çap edir.