Печать
Категория: Uncategorised
Просмотров: 42

Исследуем формулу Эйлера как генератор простых чисел.

Cn=n*n+n+41

Напишем код на Python и Forth для проверки количества простых чисел при n = от 0 до 100, 1000, 10000, 50000 и 65000.

Рассмотрим также C=27941 как замену 41, и сделаем вывод что многочлен с таким свободным членом генерирует больше простых чисел.

Код для подсчета количества простых чисел, генерируемое формулой Cn=n*n+n+41 (Cn=n*n+n+27941) на ЯП Forth.

S" lib\include\float2.f" INCLUDED
S" lib\include\facil.f" INCLUDED

: TIME TIME&DATE 2DROP 24 * + 60 * + 60 * + ;

: IS_PRIME ( N -> D )
    DUP 4 < IF DROP 1 EXIT THEN
    DUP 2 MOD 0= IF DROP 2 EXIT THEN
    DUP 0 D>F FSQRT F>D DROP 2 + 3 DO
        DUP I MOD 0= IF DROP I 0 LEAVE THEN
    2 +LOOP IF 1 ELSE THEN
;

: TST 20 0 DO I DUP . IS_PRIME . CR LOOP ;

: EULER ( N K -> )
    0 SWAP ROT 0 DO
        DUP I DUP 1+ * +
        IS_PRIME 1 = IF SWAP 1+ SWAP THEN
    LOOP DROP
;

: MAIN
TIME
    65000 41 EULER . \ код для проверки
TIME SWAP - CR ." ZANYALO " . ." sec" ;

MAIN

Первый параметр n, второй - C=41 или C=27941.

100 41 EULER .
86 Ok
100 27941 EULER .
77 Ok

1000 41 EULER .
581 Ok
1000 27941 EULER .
599 Ok

10000 41 EULER .
4149 Ok
10000 27941 EULER .
4466 Ok

45000 41 EULER .
15571 Ok
45000 27941 EULER .
17075 Ok


Код для работы с беззнаковыми числами на Forth.

S" lib\include\float2.f" INCLUDED
S" lib\include\facil.f" INCLUDED

: TIME TIME&DATE 2DROP 24 * + 60 * + 60 * + ;

: IS_PRIME ( N -> D )
    DUP 4 U< IF DROP 1 EXIT THEN
    DUP 2 UMOD 0= IF DROP 2 EXIT THEN
    DUP 0 D>F FSQRT F>D DROP 2 + 3 DO
        DUP I UMOD 0= IF DROP I 0 LEAVE THEN
    2 +LOOP IF 1 ELSE THEN
;

: TST 20 0 DO I DUP . IS_PRIME . CR LOOP ;

: EULER ( N K -> )
    0 SWAP ROT 0 DO
        DUP I DUP 1+ * +
        IS_PRIME 1 = IF SWAP 1+ SWAP THEN
    LOOP DROP
;

: MAIN
TIME
    50000 27941 EULER . \ код для проверки
TIME SWAP - CR ." ZANYALO " . ." sec" ;

MAIN

Без измерения времени выполнения:

50000 41 EULER .
17071 Ok
50000 27941 EULER .
18776 Ok

65000 41 EULER .
21631 Ok
65000 27941 EULER .
23793 Ok

С измерением времени выполнения:

MAIN \ 50000 27941 EULER
18776
ZANYALO 1 sec Ok

MAIN \ 50000 41 EULER
17071
ZANYALO 0 sec Ok

MAIN \ 65000 27941 EULER
23793
ZANYALO 2 sec Ok

MAIN \ 65000 41 EULER
21631
ZANYALO 2 sec Ok

Только при n=100, формула Эйлера с C=41 генерирует больше простых чисел, чем с C=27941. При n = 1000, 10000, 50000 и 65000 - C=27941 "побеждает", генерирует больше простых чисел.

Forth работает только с 32 битными числами (примерно +/- 2 миллиарда). Квадратный корень из 2**31 грубо 46000 плюс значения остальных членов суммы, то есть можем спокойно прогнать n до 45000. При работе с беззнаковыми числами - квадратный корень из 2**32=65536, а это значит, что можем увеличить диапазон до 65000.


Код на Python проще и понятнее (приведен ниже, сравните сами), но выполняется примерно в 15 раз дольше. Также минусом Forth является отсутствие библиотек для работы с длинными числами.

Код для подсчета количества простых чисел, генерируемое формулой Cn=n*n+n+41 (Cn=n*n+n+27941) на ЯП Python.

import time

def is_prime(n):
    if n%2 == 0:
        return 2
    for i in range(3,int(n**0.5)+1,2):
        if n%i == 0:
            return i
    return 1


def Euler(m,k):
    start_time = time.time()
    c=0
    for i in range(m):
        n=i*(i+1)+k
        if is_prime(n)==1:
            c+=1
    end_time = time.time()
    elapsed_time = end_time - start_time
    print(f"Время выполнения: {elapsed_time:.2f} секунд")
    return c

Euler(100,41)
Время выполнения: 0.00 секунд
86
Euler(100,27941)
Время выполнения: 0.00 секунд
77

Euler(1000,41)
Время выполнения: 0.01 секунд
581
Euler(1000,27941)
Время выполнения: 0.03 секунд
599

Euler(10000,41)
Время выполнения: 0.72 секунд
4149
Euler(10000,27941)
Время выполнения: 0.78 секунд
4466

Euler(45000, 41)
Время выполнения: 15.91 секунд
15571
Euler(45000, 27941)
Время выполнения: 16.98 секунд
17075

Euler(50000, 41)
Время выполнения: 19.69 секунд
17071

Euler(50000, 27941)
Время выполнения: 21.69 секунд
18776

Euler(65000, 41)
Время выполнения: 35.07 секунд
21631

Euler(65000, 27941)
Время выполнения: 38.62 секунд
23793

Euler(100000,41)
Время выполнения: 85.23 секунд
31985
Euler(100000,27941)
Время выполнения: 93.43 секунд
35150

 

Двенадцать новых чисел для формулы Эйлера:

Для 55661 процент простых чисел 19214 / 50000 * 100% = 38.428%
Для 72491 процент простых чисел 19120 / 50000 * 100% = 38.24%

115721 19860 / 50000 * 100 % = 39,72%
136517 19392 / 50000 * 100 % = 38,784%

247757 21203 / 50000 * 100 % = 42,406%
239621 19812 / 50000 * 100 % = 39,624%
206807 19248 / 50000 * 100 % = 38,496%

333491 19576 / 50000 * 100 % = 39,152%
361637 19596 / 50000 * 100 % = 39,192%
383681 19193 / 50000 * 100 % = 38,386%

487451 19035 / 50000 * 100 % = 38,07%
460631 18727 / 50000 * 100 % = 37,454%

 

Euler(10000, 55661)
Время выполнения: 0.80 секунд
4544
Euler(50000, 55661)
Время выполнения: 22.43 секунд
19214

Euler(10000, 72491)
Время выполнения: 0.80 секунд
4533
Euler(50000, 72491)
Время выполнения: 22.15 секунд
19120

По сравнению с 41 и 27941, которые дают результаты:

17071 / 50000 * 100% = 34,142%
18776 / 50000 * 100% = 37,552%

 

Euler(10000, 115721)
Время выполнения: 0.85 секунд
4690
Euler(50000, 115721)
Время выполнения: 23.50 секунд
19860

Euler(10000, 136517)
Время выполнения: 0.83 секунд
4609
Euler(50000, 136517)
Время выполнения: 23.15 секунд
19392

Euler(10000, 247757)
Время выполнения: 0.91 секунд
5027
Euler(50000, 247757)
Время выполнения: 25.15 секунд
21203

Euler(10000, 239621)
Время выполнения: 0.86 секунд
4724
Euler(50000, 239621)
Время выполнения: 23.55 секунд
19812

Euler(10000, 206807)
Время выполнения: 0.83 секунд
4601
Euler(50000, 206807)
Время выполнения: 22.77 секунд
19248

Euler(10000, 333491)
Время выполнения: 0.85 секунд
4668
Euler(50000, 333491)
Время выполнения: 23.26 секунд
19576

Euler(10000, 361637)
Время выполнения: 0.85 секунд
4634
Euler(50000, 361637)
Время выполнения: 23.33 секунд
19596

Euler(10000, 383681)
Время выполнения: 0.84 секунд
4612
Euler(50000, 383681)
Время выполнения: 22.72 секунд
19193

Euler(10000, 487451)
Время выполнения: 0.84 секунд
4537
Euler(50000, 487451)
Время выполнения: 22.47 секунд
19035

Euler(10000, 460631)
Время выполнения: 0.81 секунд
4439
Euler(50000, 460631)
Время выполнения: 22.30 секунд
18727

Плюс еще 26 свободных членов для формулы Эйлера для генерации простых чисел:

10000 595937 EULER .
4978 Ok
50000 595937 EULER .
21081 Ok

10000 579431 EULER .
4589 Ok
50000 579431 EULER .
19288 Ok

10000 601037 EULER .
4604 Ok
50000 601037 EULER .
19341 Ok

10000 701147 EULER .
4712 Ok
50000 701147 EULER .
20013 Ok

10000 771581 EULER .
4669 Ok
50000 771581 EULER .
19520 Ok


10000 765197 EULER .
4666 Ok
50000 765197 EULER .
19787 Ok

10000 722231 EULER .
4609 Ok
50000 722231 EULER .
19539 Ok

10000 878357 EULER .
4510 Ok
50000 878357 EULER .
19133 Ok

10000 1544987 EULER .
4809 Ok
50000 1544987 EULER .
20431 Ok

10000 1974881 EULER .
4643 Ok
50000 1974881 EULER .
19932 Ok

10000 1272851 EULER .
4570 Ok
50000 1272851 EULER .
19428 Ok

10000 1840997 EULER .
4563 Ok
50000 1840997 EULER .
19388 Ok

10000 1000817 EULER .
4556 Ok
50000 1000817 EULER .
19467 Ok

10000 1257911 EULER .
4519 Ok
50000 1257911 EULER .
19169 Ok

10000 1850747 EULER .
4511 Ok
50000 1850747 EULER .
19344 Ok

10000 1426697 EULER .
4495 Ok
50000 1426697 EULER .
19234 Ok

10000 1087211 EULER .
4462 Ok
50000 1087211 EULER .
18909 Ok

10000 2640161 EULER .
4798 Ok
50000 2640161 EULER .
20568 Ok

10000 2367767 EULER .
4767 Ok
50000 2367767 EULER .
20428 Ok

10000 2603297 EULER .
4595 Ok
50000 2603297 EULER .
19605 Ok

10000 2719391 EULER .
4580 Ok
50000 2719391 EULER .
19713 Ok

10000 2094341 EULER .
4564 Ok
50000 2094341 EULER .
19397 Ok

10000 2655671 EULER .
4488 Ok
50000 2655671 EULER .
19153 Ok

10000 2039747 EULER .
4440 Ok
50000 2039747 EULER .
19027 Ok

10000 2567177 EULER .
4435 Ok
50000 2567177 EULER .
19276 Ok

10000 2960381 EULER .
4387 Ok
50000 2960381 EULER .
18881 Ok