Решето на Аткин
Облик
За информацията в тази статия или раздел не са посочени източници. Въпросната информация може да е непълна, неточна или изцяло невярна. Имайте предвид, че това може да стане причина за изтриването на цялата статия или раздел. |
Решето на Аткин е метод за намиране на всички прости числа, които не надвишават дадена естествения лимит. За разлика от Решето на Ератостен, което последователно елиминира числа, кратни на вече намерени прости числа, този алгоритъм извършва предварително пресяване и след това елиминира от намерените числа кратни на прости числа на квадрат, поради което той има теоретично по-добър индикатор за асимптотична сложност .
Автори: Артър Оливър Лонсдейл Аткин, Даниел Джулиъс Бърнстейн (Английски Arthur Oliver Lonsdale Atkin, Daniel Julius Bernstein).
Алгоритъм
[редактиране | редактиране на кода]- Числата 2, 3 и 5 са очевидно прости.
- Създава се “решето” - списък, който свързва всяко естествено число n от диапазона (5; лимит] с флаг "прост\съставен". Първоначално всички флагове са зададени на " съставна” позиция.
- За следващото n от диапазона (5; limit] се намира остатъкът от деленето на 60:
- 1, 13, 17, 29, 37, 41, 49, 53: уравнение - 4x² + y² = n; (1)
- 7, 19, 31, 43: уравнение - 3x² + y² = n; (2)
- 11, 23, 47, 59: уравнение - 3x² − y² = n (за x > y) (3)
- Остатъчна стойност, която не е равна на никоя от горните, показва, че n е съставно число и следователно се изключва от по-нататъшно разглеждане. В противен случай, ако съответното уравнение има нечетен брой решения (двойки естествени стойности x и y), n се отбелязва в "решето" като "просто".
- Процедурата се повтаря, започвайки от стъпка 3, докато бъдат претърсени всички n ≤ limit.
- Накрая, за всяко намерено просто число n, всички кратни на неговия квадрат се маркират в "решето" като "съставно".
Реализации
[редактиране | редактиране на кода]Реализациите по-долу предприемат следните стъпки за оптимизиране на изчисленията:
- Simple\composite флаговете се съхраняват пакетирани в масив от битове (
vector<bool>
за C++,BitArray
за C#,BitSet
за Java,BitVec
за Rust и др.), върнат от функцията. Стойността на n-тия бит true съответства на просто n, false на съставно. - Умножението на степен две се извършва с помощта на операция за побитово преместване (<<). Например
a << 2
вместо4 * a
. - За да се избегне препълване, изчисленията се извършват в тип дълго цяло число; стойностите се въвеждат в „ситото“ в тип редовно цяло число (
unsigned long long
/unsigned
в C++,long
/int
в C# и Java,u64
/u32
в Rust). - Квадратите на последователните естествени числа се изчисляват по формулата (x + 1)² = x² + 2x + 1, т.е. чрез събиране на последователни нечетни числа. С други думи, ако квадрати е поредица от квадрати на естествени числа {0² = 0, 1² = 1, 2² = 4...}, а коефициенти е поредица от нечетни числа {1, 3, 5...}, след това квадратi+1 = квадратi + шансовеi (за всеки i ≥ 0 ).
- n се дели с остатък на 12 (не на 60). Получените стойности 1 и 5 съответстват на случай (1), 7 - (2), 11 - (3), други - съставни n.