Решето Ератосфена в 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 дуже велике, а оперативна пам'ять обмежена.

Він виконується за час O(n log log n), що близько до лінійного. Генерація кожного простого числа менше десяти мільйонів займає лише частку секунди на сучасному ноутбуці, що робить сито найшвидшим практичним вибором для малих та середніх діапазонів.

Сучасні прискорювачі штучного інтелекту пришвидшують пошук великих простих чисел, паралелізуючи решета на графічних процесорах та процесорах TPU. Моделі машинного навчання також допомагають прогнозувати перспективні діапазони кандидатів, зменшуючи навантаження на тести Міллера-Рабіна та інші тести на простоту, що використовуються для генерації ключів RSA.

Так. Репетитори зі штучним інтелектом генерують покрокові tracвізуалізують складене виключення, пропонують оптимізації, такі як колесо факторизації, та інтерактивно пояснюють докази. Вони допомагають учням розвивати інтуїцію для меж гармонійних рядів та аргументів складності за решетом.

Підсумуйте цей пост за допомогою: