Эротосфена Решето

Эротосфена Решето



🛑 👉🏻👉🏻👉🏻 ИНФОРМАЦИЯ ДОСТУПНА ЗДЕСЬ ЖМИТЕ 👈🏻👈🏻👈🏻

































Эротосфена Решето
Задачи и их решения / Решето Эратосфена
Решето Эратосфена — алгоритм нахождения всех простых чисел до некоторого целого числа N, который приписывают древнегреческому математику Эратосфену Киренскому. Название алгоритма говорит о принципе его работы, то есть решето подразумевает фильтрацию, в данном случае фильтрацию всех чисел за исключением простых. По мере обработки массива чисел нужные числа (простые) остаются, а ненужные (составные) исключаются.
Сама проблема получения простых чисел занимает ключевое место в математике, на ней основаны некоторые криптографические алгоритмы, например RSA.
Для нахождения всех простых чисел не больше заданного числа N нужно выполнить следующие шаги:
Все оставшиеся в массиве числа являются простыми числами от 2 до N
На рисунке проиллюстрирован алгоритм поиска простых чисел. Числа, отмеченные белым, являются удаленными.



 
Реализация на C++
#include
using namespace std;
int main()
{
  int n;
  cout << "n= ";
  cin >> n;
  int *a = new int[n + 1];
  for (int i = 0; i < n + 1; i++)
    a[i] = i;
  for (int p = 2; p < n + 1; p++)
  {
    if (a[p] != 0)
    {
      cout << a[p] << endl;
      for (int j = p*p; j < n + 1; j += p)
        a[j] = 0;
    }
  }
  cin.get(); cin.get();
}
Ваш e-mail не будет опубликован. Обязательные поля помечены *

Решето Эратосфена, попытка минимизировать память / Хабр
MAXimal :: algo :: Решето Эратосфена
🎦 Решето Эратосфена. Совершенно та же Википедия. Только лучше. // WIKI 2
Решето Эратосфена - YouTube
Решето Эратосфена
добавлено: 10 Jun 2008 17:57
редактировано: 23 Mar 2012 3:53
Решето Эратосфена — это алгоритм, позволяющий найти все простые числа в отрезке за операций.
Идея проста — запишем ряд чисел , и будем вычеркивать сначала все числа, делящиеся на , кроме самого числа , затем деляющиеся на , кроме самого числа , затем на , затем на , , и все остальные простые до .
Сразу приведём реализацию алгоритма:
Этот код сначала помечает все числа, кроме нуля и единицы, как простые, а затем начинает процесс отсеивания составных чисел. Для этого мы перебираем в цикле все числа от до , и, если текущее число простое, то помечаем все числа, кратные ему, как составные.
При этом мы начинаем идти от , поскольку все меньшие числа, кратные , обязательно имеют простой делитель меньше , а значит, все они уже были отсеяны раньше. (Но поскольку легко может переполнить тип , в коде перед вторым вложенным циклом делается дополнительная проверка с использованием типа .)
При такой реализации алгоритм потребляет памяти (что очевидно) и выполняет действий (это доказывается в следующем разделе).
Докажем, что асимптотика алгоритма равна .
Итак, для каждого простого будет выполняться внутренний цикл, который совершит действий. Следовательно, нам нужно оценить следующую величину:
Вспомним здесь два известных факта: что число простых, меньше либо равных , приблизительно равно , и что -ое простое число приблизительно равно (это следует из первого утверждения). Тогда сумму можно записать таким образом:
Здесь мы выделили первое простое из суммы, поскольку при согласно приближению получится , что приведёт к делению на нуль.
Теперь оценим такую сумму с помощью интеграла от той же функции по от до (мы можем производить такое приближение, поскольку, фактически, сумма относится к интегралу как его приближение по формуле прямоугольников):
Первообразная для подынтегральной функции есть . Выполняя подстановку и убирая члены меньшего порядка, получаем:
Теперь, возвращаясь к первоначальной сумме, получаем её приближённую оценку:
Более строгое доказательство (и дающее более точную оценку с точностью до константных множителей) можно найти в книге Hardy и Wright "An Introduction to the Theory of Numbers" (стр. 349).
Самый большой недостаток алгоритма — то, что он "гуляет" по памяти, постоянно выходя за пределы кэш-памяти, из-за чего константа, скрытая в , сравнительно велика.
Кроме того, для достаточно больших узким местом становится объём потребляемой памяти.
Ниже рассмотрены методы, позволяющие как уменьшить число выполняемых операций, так и значительно сократить потребление памяти.
Самый очевидный момент — что для того, чтобы найти все простые до , достаточно выполнить просеивание только простыми, не превосходящими корня из .
Таким образом, изменится внешний цикл алгоритма:
На асимптотику такая оптимизация не влияет (действительно, повторив приведённое выше доказательство, мы получим оценку , что, по свойствам логарифма, асимптотически есть то же самое), хотя число операций заметно уменьшится.
Поскольку все чётные числа, кроме , — составные, то можно вообще не обрабатывать никак чётные числа, а оперировать только нечётными числами.
Во-первых, это позволит вдвое сократить объём требуемой памяти. Во-вторых, это уменьшит число делаемых алгоритмом операций примерно вдвое.
Заметим, что алгоритм Эратосфена фактически оперирует с битами памяти. Следовательно, можно существенно сэкономить потребление памяти, храня не байт — переменных булевского типа, а бит, т.е. байт памяти.
Однако такой подход — "битовое сжатие" — существенно усложнит оперирование этими битами. Любое чтение или запись бита будут представлять из себя несколько арифметических операций, что в итоге приведёт к замедлению алгоритма.
Таким образом, этот подход оправдан, только если настолько большое, что байт памяти выделить уже нельзя. Сэкономив память (в раз), мы заплатим за это существенным замедлением алгоритма.
В завершение стоит отметить, что в языке C++ уже реализованы контейнеры, автоматически осуществляющие битовое сжатие: vector и bitset<>. Впрочем, если скорость работы очень важна, то лучше реализовать битовое сжатие вручную, с помощью битовых операций — на сегодняшний день компиляторы всё же не в состоянии генерировать достаточно быстрый код.
Из оптимизации "просеивание простыми до корня" следует, что нет необходимости хранить всё время весь массив . Для выполнения просеивания достаточно хранить только простые до корня из , т.е. , а остальную часть массива строить поблочно, храня в текущий момент времени только один блок.
Пусть — константа, определяющая размер блока, тогда всего будет блоков, -ый блок () содержит числа в отрезке . Будем обрабатывать блоки по очереди, т.е. для каждого -го блока будем перебирать все простые (от до ) и выполнять ими просеивание только внутри текущего блока. Аккуратно стоит обрабатывать первый блок — во-первых, простые из не должны удалить сами себя, а во-вторых, числа и должны особо помечаться как не простые. При обработке последнего блока также следует не забывать о том, что последнее нужное число не обязательно находится в конце блока.
Приведём реализацию блочного решета. Программа считывает число и находит количество простых от до :
Асимптотика блочного решета такая же, как и обычного решета Эратосфена (если, конечно, размер блоков не будет совсем маленьким), зато объём используемой памяти сократится до и уменьшится "блуждание" по памяти. Но, с другой стороны, для каждого блока для каждого простого из будет выполняться деление, что будет сильно сказываться при меньших размерах блока. Следовательно, при выборе константы необходимо соблюсти баланс.
Как показывают эксперименты, наилучшая скорость работы достигается, когда имеет значение приблизительно от до .
Алгоритм Эратосфена можно преобразовать в другой алгоритм, который уже будет работать за линейное время — см. статью "Решето Эратосфена с линейным временем работы". (Впрочем, этот алгоритм имеет и недостатки.)

Обнаженная Мария Порошина
Отсос Петрович
Букина Сосет Член
Курские Студенты Порно Скачать
Медсестри Большие Сиськи

Report Page