генерация массива простых чисел

Тема в разделе "WASM.A&O", создана пользователем EvilsInterrupt, 29 окт 2004.

  1. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Господа

    мне надо сгенерировать совокупность простых чисел,

    каждое число будет иметь размер в 32 разряда. К примеру 1 это:

    00000001h,2 это 00000002h и т.д. Буду, я это хранить в файле

    asked.dat. Чтобы в будущем не мучиться и негенерировать боль-

    шие простые числа.



    передо мной несколько путей и только 2 известны мне:

    1. Путь решета Эратосфена из Василенко, но мне не нравится, уж

    больно много памяти надо!

    2. Либо перебор, че нить вроде этого:



    REPT 3

    ; так как 1,2,3 - простые числа

    inc eax

    mov dword ptr[esi],eax

    add esi,4

    ENDM



    use:

    inc eax,eax

    jnc short exit_simple_number

    push eax

    call simple_number,eax

    test eax,eax

    jnz short next

    pop eax

    jmp use

    next:

    pop eax

    mov dword ptr[esi],eax ; в esi ук.массива

    add esi,4

    jmp use



    exit_simple_number:





    simple_number proc number:lol: WORD

    pusha

    mov eax,number

    mov ebp,eax

    round_s_n:

    xor edx,edx

    dec ebp

    test ebp,0fffeh ; если 1, то выход

    ; ebp обнулиться не успеет

    jz short exit_s_n

    div ebp

    test edx,edx

    jz short exit_s_n

    jmp round_s_n



    loop round_s_n

    dec esi



    exit_s_n:

    popa

    ret

    simple_number endp



    Просьба указать мне на мои ошибки, как програмные так и на

    логические, т.е. можно ли пойти по другому пути.
     
  2. flankerx

    flankerx New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2004
    Сообщения:
    423
    Адрес:
    Moscow, Russia
    ИМХО проверить 32-х битное число на простоту быстрее всего перебором: нужно не более sqrt(2^32) = 2^16 делений чтобы точно определить, является ли число простым или нет и получить его полное разложение на множители.. я думаю, это не так ужи и долго для единовременных вычислений..

    Другие варианты, безусловно, существуют, но в данной задаче я бы не стал их использовать..
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    flankerx



    Ты плохо прочитал, мне не одно число надо, а совокупность простых чисел от 1h до ближайшего к 0ffffffffh причем все числа dword!
     
  4. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Примерно 1/10 натуральных чисел - простые. Если записывать простые числа как двойные слова, то потребуется около 1.6 ГБ. Можно вместо этого использовать битовый массив, представляющий все нечетные числа - тогда потребуется всего 256 МБ. Такая таблица вполне уместится в памяти современного десктопа, а значит можно будет использовать метод Эратосфена.

    Можно еще проверять делимость числа на все ПРОСТЫЕ числа, не превышающие квадратный корень тестируемого. Тогда потребуется не более 6542 делений на одно число.

    Sapienti sat.
     
  5. B_108

    B_108 New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    62
    Есть такая функция pi(x) - для любого натурального x она выдает ПРИМЕРНОЕ количество простых чисел не превышающих x,

    при больших х она стремится к, если не ошибаюсь, x/ln(x)

    (днем точно скажу),

    это так... для оценки :)

    А вообще оптимальный алгоритм на мой взгляд следующий:

    1) числа 2 3 заносим в наш массив

    2) прибавляем к предыдущему числу 2

    3) проверяем делимость текущего числа на уже заполненные элементы массива, пока эти элементы не превышают sqrt() от нашего кандидата

    4) если он ни делитя ни на одно из этих чисел,

    добавляем его в массив и переходим к шагу 2

    5) переходим к шагу 2, если еще не все числа перебрали



    ЗЫ проверять делимость на 2 вовсе не обязательно, ведь мы потом берем только нечетные числа...
     
  6. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Вот тут подумалось...



    Алгоритм "эратосфеново решето" вычеркивает из таблицы из N чисел все числа общего вида (т. е. не простые). Всякое такое число имеет простые делители, из которых хотя бы один лежит в диапазоне [2..sqrt(N)]. Следовательно, если вычеркнуть все числа, кратные простым числам из диапазона [2..int(sqrt(N))], то все оставшиеся числа будут простыми.



    Если N = 2^32-1, то достаточно вычеркнуть числа, кратные [2..65521] (65521 - максимальное простое число, меньшее 65536). Количество этих "контрольных" чисел невелико (6542). Вырисовывается такая идея:



    1) разбиваем всю таблицу чисел на блоки, умещающиеся в памяти;

    2) создаем таблицу из 6542 элементов, в которую записываем "контрольные" простые числа < 65536 и текущие числа, кратные "контрольным";

    3) для каждого "контрольного" числа выполняем цикл, вычеркивающий в текущем блоке все "кратные" числа; сохраняем в массиве очередное "кратное" число, находящееся в следующем блоке;

    4) когда все "контрольные" числа обработаны, сбрасываем текущий блок на диск, генерируем следующий блок и переходим к пункту 3), и так пока не обработаем все 4G чисел.



    Немного сумбурно. Постараюсь к вечеру написать программу (Object Pascal с ассемблерными вставками устроит ? :)
     
  7. Grevgeny

    Grevgeny New Member

    Публикаций:
    0
    Регистрация:
    9 дек 2003
    Сообщения:
    16
    Адрес:
    Russia
    \masm32\EXAMPL10\CONSOLE\HASHAPP\PRIMES\

    Лежит одноименный файлик с исходником выдает текстовый файл простых чисел от 0 до 65535. Вот от него и пляши. :)
     
  8. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Выкладываю, что получилось.

    Программа на Object Pascal (для простоты), но все вычисления на ассемблере. Пишет в файл битовый массив блоками по 4 МБ.

    Вроде бы, все работает правильно, только медленно.

    [​IMG] 1575220741__Eratos4G.zip
     
  9. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    обязательно гляну!
     
  10. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    Я делал так:

    1. Решетом Эратосфена находишь все простые числа, не превышающие 65536

    2. Выбераешь первые несколько чисел и перемножаешь. Например, возьмём 2, 3 и 5. Перемножаешь их и получаешь 30. После этого из диапазона 0..29 вычёркиваешь все числа, делящиеся на 2, 3 или 5. Получаешь числа

    1, 7, 11, 13, 17, 19, 23, 29 (в данном случае все получились простые, но так будет не всегда). Тогда нужно проверять на делимость лишь числа вида

    30k+1

    30k+7

    30k+11

    30k+13

    30k+17

    30k+19

    30k+23

    30k+29

    т. е. изначально

    x=65537 (первое чило, большее 65536 нашего вида, 65536=30k+17)

    проверить x на делимость на простые числа, не превышающие sqrt(x). если не делится, запомнить x

    x+=(19-17)

    повторить проверку

    x+=(23-19)

    ....

    и так далее, пока x<=0FFFFFFFFh

    3. Записывать в файл можно полуразность простых чисел, запихивая её в один байт
     
  11. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Loger



    Спасибо на добром слове!
     
  12. ovod

    ovod New Member

    Публикаций:
    0
    Регистрация:
    20 янв 2004
    Сообщения:
    26
    Адрес:
    г. Нелидово Тверской обл.
    Вот что братья индусы напридумали в 2002 году ttp://www.cse.iitk.ac.in/news/primality.pdf

    В частности, вырезка оттуда

    http://nelidovo2.narod.ru/simple.png
     
  13. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    ovod



    Причем здесь это? Повыпендриваться описанием алгоритмов захотелось?
     
  14. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Не стал мудрить и искать оригинальных решений, просто сделал перебор, подобный тому что описал в начале топа. Токо, есно, улучшил! Говорят, друзья, что методом алгоритма Эвклида, как то можно простые числа генерить. Но я плохой математик и не вижу КАК? Даже не смотря на темы форума, к примеру поднятую Володей. Ну, чтож. Буду перебирать
     
  15. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Loger, что это за алгоритм такой? Нельзя ли поподробнее? И с математическим обоснованием.

    Что же касается полуразностей, то это не очень хорошая идея. Разности можно использовать исключительно в том случае, если нужен только последовательный перебор простых чисел. А в условии задачи об этом ничего не говорится. :)
     
  16. volodya

    volodya wasm.ru

    Публикаций:
    0
    Регистрация:
    22 апр 2003
    Сообщения:
    1.169
    Есть и другой алгоритм. Называется "алгоритм колеса". В книгу пойдет. EvilsInterrupt, если тебе совсем не в терпеж, дам наброски в конце недели. Если может подождать - жди и ты.
     
  17. Loger

    Loger New Member

    Публикаций:
    0
    Регистрация:
    28 авг 2003
    Сообщения:
    71
    Адрес:
    Minsk
    ava:

    алгоритм мой ;)

    математическое обоснование писать не буду, но нетрудно доказать, что что числа вида (30k+n), где n не пренадлежит {1,7,11,13,17,19,23,29} не являются простыми (они делятся на 2, 3 или 5). А остальные числа мы проверяем на простоту делением.

    если нужен произвольный доступ к простым числам, скорость доступа можно увеличить, записывая каждое n-нное число полностью. например, если писать каждое 29-е число полностью то получится

    struct primes_block{

    unsigned long first;

    unsigned char primes[28];

    }

    учитывая, что данные в кэш грузятся по 32 байта, при правильном выравнивании массива таких блоков, потери производительности почти не будет
     
  18. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Loger, я вот тут подумал над твоим алгоритмом и наконец-то понял, что это действительно очевидно :)



    "Интра-фреймы" по-своему решают проблему поиска чисел, но одновременно увеличивают размер файла, так что основное преимущество использования полуразностей - компактность (по сравнению с полной записью) - уменьшается. К тому же следует иметь в виду, что полуразность может оказаться больше 256. В данном случае все в порядке - максимальная полуразность равна 168 - но это выяснилось только после создания таблицы. >:)
     
  19. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    All



    Дружно пошлем все володины проблемы на ..., что бы он быстрее труд на бацал!
     
  20. HaDron

    HaDron New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2004
    Сообщения:
    4
    Адрес:
    Russia
    Я так понимаю что массив простых чисел нужен для проверки большого числа на простоту ?



    Я в свое время так сделал массив занял 800+ мег. :)



    После чего он оказался ненужен так как есть как минимум 2 способа проверки числа на простоту (читай Кнута).



    PS: Может я не понял для чего все это нужно , так что сильо не пинайте :)