Решето на Ератостен в Python & C++

⚡ Умно обобщение

Ситото на Ератостен е класически алгоритъм за прости числа, който филтрира съставни числа чрез итеративно маркиране на кратните на всяко просто число, оставяйки само прости числа в рамките на избрана горна граница за бързо търсене.

  • 🔢 Основна идея: Маркирайте кратните на всяко просто число, започвайки от 2, за да изолирате простите числа до n.
  • 🧮 Ограничен цикъл: Итерирайте само до корен квадратен от n, защото по-големите фактори вече са елиминирани.
  • ⚡ Времева сложност: Алгоритъмът работи в O(n log log n), което е почти линейно за практически диапазони.
  • ✅ Сегментирано сито: Разделянето на диапазона на блокове намалява спомагателната памет от O(n) до O(√n).
  • 🧪 Случаи на употреба: Криптографията, хеширането, конкурентното програмиране и теорията на числата разчитат на бързо генериране на прости числа.

Решето на Ератостен в Python

Какво е ситото на Ератостен?

Решетото на Ератостен е най-простото сито за прости числа. Това е алгоритъм за прости числа, използван за откриване на всяко просто число в даден лимит. Съществуват няколко сита за прости числа, включително ситото на Ератостен, ситото на Аткин и ситото на Сундарам.

Думата "сито„“ се отнася до прибор, който филтрира вещества. В същия дух, алгоритъмът за сито в Python и други езици се отнася до метод, който филтрира прости числа от списък с цели числа.

Този алгоритъм филтрира прости числа, използвайки итеративен подход. Процесът на филтриране започва с най-малкото просто число. Простото число е естествено число, по-голямо от 1, което има само два делителя, а именно 1 и самото число. Numbers които не са прости числа, се наричат ​​съставни числа.

Защо да използваме ситото на Ератостен?

При метода „Рето на Ератостен“ първо се избира малко просто число и всички негови кратни се филтрират. Процесът протича в цикъл в даден диапазон, като ефективно се получава всяко просто число до n, без да се извършва пробно деление на всеки кандидат.

Това прави ситото по-бързо от проверката на простотата едно число наведнъж. То се използва широко в теорията на числата, криптографията, хеширането и конкурентното програмиране, където много прости числа трябва да бъдат генерирани бързо.

Например:

Нека вземем числовия диапазон от 2 до 10.

Алгоритъмът Сито на Ератостен

След прилагане на ситото на Ератостен, то ще генерира списък с прости числа 2, 3, 5, 7.

Алгоритъмът Сито на Ератостен

Алгоритъм Сито на Ератостен

Ето алгоритъма за Ситото на Ератостен:

Стъпка 1) Създайте списък с числа от 2 до дадения диапазон n. Започваме с 2, защото това е най-малкото и първо просто число.

Стъпка 2) Изберете най-малкото число от списъка, x (първоначално x е равно на 2), прегледайте списъка и филтрирайте съответните съставни числа, като маркирате всички кратни на избраното число.

Стъпка 3) След това изберете следващото просто число или най-малкото немаркирано число в списъка и повторете стъпка 2.

Стъпка 4) Повторете предишната стъпка, докато стойността на x стане по-малка или равна на корен квадратен от n (x <=Алгоритъм Сито на Ератостен).

Забележка: Математическите разсъждения са доста прости. Числовият диапазон n може да се факторизира като:

n = a * b

Отново, n = Алгоритъм Сито на Ератостен * Алгоритъм Сито на Ератостен

= (фактор по-малък от Алгоритъм Сито на Ератостен) * (фактор по-голям от Алгоритъмът Сито на Ератостен)

Така че поне един от основни фактори или и двете трябва да са <= Алгоритъм Сито на ЕратостенСледователно, преминавайки до Алгоритъм Сито на Ератостен ще бъде достатъчно.

Стъпка 5) След тези четири стъпки, останалите немаркирани числа ще бъдат всички прости числа в дадения диапазон n.

Работен пример

Пример:

Нека вземем пример и да видим как работи.

За този пример ще намерим списъка с прости числа от 2 до 25. Така че, n = 25.

Стъпка 1) В първата стъпка ще вземем списък с числа от 2 до 25, тъй като сме избрали n = 25.

Алгоритъм Сито на Ератостен

Стъпка 2) След това избираме най-малкото число от списъка, x. Първоначално x = 2, защото е най-малкото просто число. След това обхождаме списъка и маркираме кратните на 2.

Кратните на 2 за дадената стойност на n са: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24.

Алгоритъмът Сито на Ератостен

Забележка: Синият цвят обозначава избраното число, а розовият - елиминираните кратни.

Стъпка 3) След това избираме следващото най-малко немаркирано число, което е 3, и повтаряме последната стъпка, като маркираме кратните на 3.

Алгоритъмът Сито на Ератостен

Стъпка 4) Повтаряме стъпка 3 по същия начин, докато x = Алгоритъмът Сито на Ератостен или 5.

Алгоритъмът Сито на Ератостен

Стъпка 5) Останалите немаркирани числа са простите числа от 2 до 25.

Алгоритъмът Сито на Ератостен

псевдо-Code

Следният псевдокод улавя основната структура на ситото на Ератостен, преди да го преведем в действителен код.

Begin
	Declare a boolean array of size n and initialize it to true
	For all numbers i : from 2 to sqrt(n)
     		IF bool value of i is true THEN
         			i is prime
         			For all multiples of i (i<n)
             			mark multiples of i as composite
Print all unmarked numbers
End

Ситото на Ератостен C/C++ Code Пример

По-долу е дадено пълно C++ имплементация на ситото на Ератостен, което отпечатва всяко просто число до избрана горна граница.

#include <iostream>
#include <cstring>
using namespace std;
void Sieve_Of_Eratosthenes(int n)
{
    // Create and initialize a boolean array
    bool primeNumber[n + 1];
    memset(primeNumber, true, sizeof(primeNumber));
    for (int j = 2; j * j <= n; j++) {
        if (primeNumber[j] == true) {
            // Update all multiples of i as false
            for (int k = j * j; k <= n; k += j)
                primeNumber[k] = false;
        }
    }
    for (int i = 2; i <= n; i++)
        if (primeNumber[i])
            cout << i << " ";
}
int main()
{
    int n = 25;
    Sieve_Of_Eratosthenes(n);
    return 0;
}

Изход:

2 3 5 7 11 13 17 19 23

Ситото на Ератостен Python Примерна програма

По-долу Python Програмата реализира същия алгоритъм, използвайки булев списък и while цикъл.

def SieveOfEratosthenes(n):
# Create a boolean array
	primeNumber = [True for i in range(n+2)]
	i = 2
	while (i * i <= n):
		if (primeNumber[i] == True):
			# Update all multiples of i as false
			for j in range(i * i, n+1, i):
				primeNumber[j] = False
		i += 1
	for i in range(2, n):
		if primeNumber[i]:
			print(i)
n = 25
SieveOfEratosthenes(n)

Изход:

2
3
5
7
11
13
17
19
23

Сегментирано сито

Видяхме, че ситото на Ератостен изпълнява цикъл през целия числов диапазон. Следователно, то се нуждае от O(n) памет, за да съхранява числата. Ситуацията се усложнява, когато се опитваме да намерим прости числа в огромен диапазон, защото не е възможно да се разпредели толкова голям блок памет за по-голямо n.

Алгоритъмът може да бъде оптимизиран чрез въвеждане на някои нови функции. Идеята е да се раздели числовият диапазон на по-малки сегменти и да се изчислят простите числа в тези сегменти едно по едно. Това е ефективен начин за намаляване на сложността на пространството. Този метод се нарича a сегментирано сито.

Оптимизацията може да се постигне по следния начин:

  1. Използвайте просто сито, за да намерите прости числа от 2 до Сегментирано сито и ги съхранявайте в масив.
  2. Разделете диапазона [0…n-1] на множество сегменти с най-голям размер Сегментирано сито.
  3. За всеки сегмент, итерирайте през сегмента и маркирайте кратните на простите числа, намерени в стъпка 1. Тази стъпка изисква O(Сегментирано сито) на максимум.

Обикновеното сито изисква O(n) спомагателно пространство в паметта, докато сегментираното сито изисква O(Сегментирано сито), което е значително подобрение за голямо n. Методът има и недостатък, защото не подобрява времевата сложност.

Анализ на сложността

Разбирането както на пространствената, така и на времевата сложност ви помага да избирате между обикновеното сито и сегментираното сито за даден размер на проблема.

Космическа сложност:

Простият алгоритъм „Рето на Ератостен“ изисква O(n) памет. Сегментираното сито изисква O(Анализ на сложността) спомагателно пространство.

Времева сложност:

Времевата сложност на обикновен алгоритъм „Рето на Ератостен“ е O(n*log(log(n))). Обосновката на тази сложност е обсъдена по-долу.

За дадено число n, времето, необходимо за маркиране на съставно число (т.е. непросто число), е константно. Следователно, броят на изпълненията на цикъла е равен на:

n/2 + n/3 + n/5 + n/7 + ……∞

= n * (1/2 + 1/3 + 1/5 + 1/7 +…….∞)

Хармоничната прогресия на сумата от простите числа може да се изведе като log(log(n)):

(1/2 + 1/3 + 1/5 + 1/7 +…….∞) = log(log(n))

Така че, времевата сложност ще бъде:

T(n) = n * (1/2 + 1/3 + 1/5 + 1/7 + ……∞)

= n * log(log(n))

Следователно времевата сложност е O(n * log(log(n))).

След това ще научите за Триъгълник на Паскал.

Въпроси и Отговори

Всяко съставно число n може да се запише като произведение на два множителя, като поне един от тях трябва да е по-малък или равен на корен квадратен от n. Маркирането на кратни след тази точка е ненужно, защото всяко съставно число вече е елиминирано.

Обикновеното сито заделя O(n) памет за маркиране на всяко число, докато сегментираното сито разделя диапазона на блокове с размер √n и използва повторно паметта. Сегментираната версия е за предпочитане, когато n е много голямо и RAM паметта е ограничена.

Изпълнява се за време O(n log log n), което е близко до линейното. Генерирането на всяко просто число под десет милиона отнема само части от секундата на съвременен лаптоп, което прави ситото най-бързият практичен избор за малки до средни диапазони.

Съвременните ускорители с изкуствен интелект ускоряват търсенията на големи прости числа чрез паралелизиране на сита на графични процесори (GPU) и процесори за обработка на данни (TPU). Моделите за машинно обучение също помагат за прогнозиране на обещаващи диапазони от кандидати, намалявайки натоварването на тестовете за Miller-Rabin и други тестове за простота, използвани при генерирането на RSA ключове.

Да. Обучителите с изкуствен интелект генерират стъпка по стъпка traces, визуализират съставно елиминиране, предлагат оптимизации като факторизация на колело и обясняват доказателствата интерактивно. Те помагат на учащите да изградят интуиция за граници на хармонични редове и аргументи за сложност зад ситото.

Обобщете тази публикация с: