Простые числа вида k * 2 n +1
При решении этой вспомогательной задачи, правда, можно ограничиться перебором на меньших начальных отрезках натурального ряда. Конечно, этот способ решения вполне корректен. Но он ведет к программе, которая выглядит несколько искусственно. Фактически получится не программа, а подглядывание в раздел ответов в случае небольших значений п. Ничего плохого в этом нет. Просто этот способ реализовать нельзя, если мы не знаем нужную нам часть ответа для решаемой задачи. Поэтому мы поступим иначе. Мы вообще сделаем вид, что не знаем даже начальных значений n. Сначала найдем в программе все те начальные значения n, при которых числа вида 3*2n +1 не превосходят тех простых чисел q, которые использовались для построения таблицы. Хотя это и будет чистый перебор, перебирать придется недолго, поскольку числа вида 3*2n +1 с ростом и растут гораздо быстрее, чем n-е простое число ра. Например, если мы будем строить таблицу, используя первые 25 000 простых чисел, то перебирать без дополнительной отбраковки придется лишь три-четыре десятка значений п. Затем можно будет построить таблицу и запустить процесс предварительной отбраковки.
Поскольку проверка малых значений выполняется весьма быстро, о времени ее выполнения можно не беспокоиться. Конечно, вполне законным является и вопрос: не слишком ли рано мы запускаем отбраковку? Но мы видели, что даже отбраковка 100 000 чисел с помощью огромной таблицы, построенной с использованием первых 25 000 простых чисел, занимает не более 24 минут. Так что на предварительную отбраковку одного числа требуется совсем немного времени. Ну а выигрыш отбраковка дает уже при весьма малых значениях п. Поэтому не стоит беспокоиться из-за того, что на некотором, весьма малом отрезке отбраковка может оказаться менее эффективной, чем прямая проверка. Для таблицы, построенной с использованием первых 25 000 простых чисел, перерасход времени, например, не превысит десятка-двух секунд. Так что беспокойство по поводу того, что временные затраты на отбраковку малых значений n могут быть больше, чем на прямую проверку, необоснованно. Но перед запуском отбраковки нужно сгенерировать таблицу t. Даже если таблица строится с использованием первых 10 000 простых чисел, генерация таблицы занимает немного более полторы минуты. Кроме того, в данной программе есть еще один источник непредсказуемых временных затрат. Это показатели n, кратные 4. Давайте сначала посмотрим, что это будут за показатели. Вот нужная нам программа.
prog401 :
=
Block[{nn
=
8000
,Yes
=
0
,No
=
0
,j
=
4
), While[j
<
=
nn,
If[fx[j,t],Print[j,
","
];Yes
+
+
,No
+
+
]; j
+
=
4
];
Print[
"Yes="
,Yes,
"; No="
,No]]
В пределах первых восьми тысяч будет найдено 401 число, кратное 4, такое, что его не удастся отсеять с помощью таблицы, для генерации которой использовались 25 000 простых чисел. (Отсеяно будет 1599 чисел.) Далее приведен список тех чисел, которые кратны 4 и выдерживают отсев.
Если показатель я равен одному из этих чисел, то наименьший делитель числа 3*2n + 1, больший единицы, больше наибольшего простого модуля, использованного для составления таблицы. Вот примеры.
Factor
-
Integer [
3
*
2
^
36
+
1
]
{(
206158430209.1
}} Factorlnteger[
3
*
2
^
92
+
1
]
{{
1132314641089.1
},{
13119392730926401.1
}} Factorlnteger[
3
*
2
^
96
+
1
]
{{
392840481939253.1
},{
605040718740253.1
}} Factorlnteger [
3
*
2
^
108
+
1
]
{{
805213.1
},{
1781311693519.1
},{
678750386188027.1
}}
Таким образом, нетривиальные делители чисел 3*2n +1, показатели которых выдержали отсев, довольно велики. (Ведь если число 3*2n +1 делится на простой модуль, использованный при построении таблицы, то показатель не выдержал отсев.) Поэтому при применении функции PrimeQ могут произойти временные задержки. Давайте сосчитаем количество таких показателей в пределах первых 300 000. Вот нужная нам программа.
prog4 :
=
Block[{nn
=
30000
,Yes
=
0
,No
=
0
, j
=
4
}, While[j
<
=
nn,
If[fx[j,t],Yes
+
+
,No
+
+
]; j
+
=
4
];
Print[
"Yes="
,Yes,
"; No="
,No]]
Вот результаты счета.
prog4
//Timing
Yes
=
14451
; No
=
60549
{
1893.61
Second,Null}
Как видите, в пределах первых 300000 придется проверить только 14451 число, кратное 4. Правда, отсев остальных чисел при этом у меня занял примерно 1893 секунды, т.е. чуть больше получаса.
Хотя, как и в случае чисел 5*2n +1, время на построение таблицы окупается, поведение программы может показаться несколько неожиданным из-за временных затрат на построение таблицы и возможных временных затрат на вычисление функции PrimeQ в случае показателей, кратных 4. Действительно, сначала очень быстро печатаются первые значения п, а затем после n = 534 (на моем компьютере) происходит весьма существенная задержка. Она связана как с отсутствием искомых значений и вплоть до п = 2 208, так и с тем, что для части чисел (чуть более 11%) приходится выполнять полную проверку, которая теперь уже требует весьма ощутимых временных затрат, причем зачастую весьма непредсказуемых для показателей п, кратных 4. Затем выдача замедляется, но поведение программы выглядит вполне стабильно, пока не будет напечатан показатель n = 3 912. После этого идет большой перерыв, вплоть до w = 20 909. В приведенной ниже программе учтено все, о чем говорилось выше.
M3n[n_]:
=
Block[{j
=
1
, nnprime
=
25000
,primen
=
Prime[nnprime],nn
=
Min[n,primen]},
While [MMkn[
3
,j]
<
=
primen && j
<
=
n,
{If[MM3nPrime01[j],Print[j]], J
+
+
H; If[j]
<
n,
t
=
Sort[DeleteCases[Array[f3,nnprime,
3
], Null]];
While[j]
=
nn,
If[fx[j,t],
If[MM3nPrime01[j],Print[j]]]; j
+
+
]]]