Предположим, у меня есть натуральный номер n
, и я хочу список (или любой другой) всех простых чисел до n
.Есть ли быстрый, функциональный первичный генератор?
Классический алгоритм простого сита работает в O(n log n)
времени и O(n)
пространство - это нормально для более императивных языков, но требует внесения изменений в списки и случайный доступ на месте.
Существует функциональная версия с приоритетными очередями, которая довольно гладкая - вы можете проверить ее here. Это лучшее пространство сложности около O(n/log(n))
(асимптотически лучше, но спорное в практических масштабах). К сожалению, анализ времени неприятный, но это почти O(n^2)
(на самом деле, я думаю, это примерно O(n log(n) Li(n))
, но log(n) Li(n)
составляет примерно n
).
Асимптотически говоря, было бы лучше просто проверить правильность каждого числа при его создании, используя последовательное пробное деление, поскольку это займет всего O(1)
места и O(n^{3/2})
времени. Есть ли способ лучше?
Редактировать: Оказалось, что мои вычисления были просто неправильными. Алгоритм в статье O(n (log n) (log log n))
, который статьи объясняют и доказывают (и см. Ответ ниже), а не сложный беспорядок, который я поставил выше. Мне все равно понравится чистый алгоритм bona-fide O(n log log n)
, если он есть.
Связанная статья предлагает алгоритм Theta (n log n log log n) -time, один log n-фактор стандартного сита Eratosthenes, используя функциональную очередь приоритетов для объединения записей в массив. –
Хотя я считаю, что это по теме здесь, если вы не получите никаких ответов через некоторое время, вы также можете проверить на computercience.stackexchange. – Gilles
@DavidEisenstat, вероятно, проблема в том, что я не могу правильно рассчитать сложности. Я определенно очень запутался в этом. –