Сито Эратосфена - HeapMemoryOutOfSpace

1

Поэтому я написал код для внедрения сита эратосфенов и он хорошо работает для небольших входов !! Как только я беру n до около 1000000000, это показывает и ошибки, HeapMemoryOutOfSpace. Я здесь в блоке и не могу понять, как заставить его работать на такие большие ценности. Есть ли какая-то оптимизация, которая может быть сделана для этого? Это для онлайн-судьи, поэтому максимальное значение n является тем, которое я уже упоминал. Это не для конкуренции и только для моей собственной практики. Любая помощь будет оценена!

import java.io.*;
class PrimeGenerator
{
public static void main(String args[])
{
    try
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int t = Integer.parseInt(br.readLine());

        while(t--!=0)
        {
            String k[] = br.readLine().split(" ");

            int m = Integer.parseInt(k[0]);
            int n = Integer.parseInt(k[1]);

            long arr[] = new long[n+2];

            for(long a=2;a<=n;a++)
            {
                arr[(int)a] = 1;
            }

            for(long a=2;a*a<=n;a++)
            {
                if(arr[(int)a]==1)
                {
                    for(long b=a;b*a<=n;b++)
                    {
                        arr[(int)(a*b)]=0;
                    }
                }
            }

            for(int a=2;a<=n;a++)
            {
                if(arr[a]==1&&arr[a]>=m)
                {
                    System.out.println(a);
                }
            }
            System.out.println();
        }
    }
    catch(Throwable e)
    {
        e.printStackTrace();
    }

}
}
  • 0
    1000000000 скоро ? Сколько вы предсказываете, вы должны вписаться в вашу оперативную память.
  • 0
    Можете ли вы уточнить, каковы ваши входы? t - количество случаев
Показать ещё 1 комментарий
Теги:
error-handling
sieve-of-eratosthenes
heap-memory

3 ответа

1
Лучший ответ

Opetion уже указал на несколько структурных проблем с вашим кодом; некоторые биты программы вообще не имеют никакого смысла (например, if (arr[a] == 1 && arr[a] >= m)). Не говоря уже о том, что код не реализует Сито Эратосфена, хотя он использует аналогичную логику. Эратосфенс удаляет кратность простого числа p, начиная с индекса p * p, а затем увеличивая на p (т.е. Добавляя аддитивно).

Два наблюдения, предполагая, что это что-то вроде проблемы SPOJ PRIME1, где вы должны печатать простые числа между M и N:

(1) Вы используете одно 64-разрядное целое (Java long) для представления каждого номера кандидата вместо одного бита. Дальнейшее экономия пространства и времени возможно за счет исключения всех четных чисел из массива, при необходимости, притянув номер 2 из тонкого воздуха. В бит-упакованном представлении только для коэффициентов требуется только 1/128-е место, которое вы используете сейчас. В java.util.BitSet тяжелая работа уже выполнена.

(2) Для просеивания чисел в диапазоне [M, N] нет необходимости просеивать все числа между 2 (или 3) и N. На самом деле, такие задачи, как SPOJ, предназначены для того, чтобы сделать вас тайм-аут, если вы попробуете это, даже несмотря на то, что он выполнен с хорошим чистым высокопроизводительным кодом. Для просеивания диапазона [M, N] вам понадобятся только потенциальные первичные коэффициенты вплоть до sqrt(N) которые составляют всего несколько тысяч, и массив размеров (N-M+1) для фактического просеивания. Или (NM)/2, для сита с шансом. Это займет всего несколько миллисекунд и не так много места.

Для SPOJ вам даже не нужно использовать представления упакованных бит или простое рассеивание. Просто сосредоточившись только на оконном просеивании, вы можете легко справиться с задачей, имея свободное пространство и время.

0

Вам нужно настроить JVM и увеличить размер кучи.

Если вы запускаете программу на консоли, вы можете увеличить размер следующим образом:

java -Xmx6g myprogram

Эта команда увеличивает размер кучи до 6 гигабайт, увеличивая это независимо от вашей системы.

Если вы используете eclipse или другую среду IDE, вам нужно будет найти, как настроить JVM для запуска этой программы в вашей среде IDE, но она, вероятно, будет напоминать приведенную выше команду.

  • 0
    да уж !! Дело в том, что я могу это сделать, но он будет работать только на моем компьютере с настроенной мной средой разработки, но мне нужно отправить ее в Интернете, чтобы я мог выполнить ее в своей системе (онлайн-судья) ??
0

Для простых чисел до 1000000000 вам не нужно увеличивать размер кучи в правильной реализации.
Некоторые проблемы с вашей реализацией Сито Эратосфена:

  • Зачем использовать longs, когда вы просто сохраняете 0 и 1?
    Существует примитивный тип, который использует только 0 и 1 (false и true), называемый boolean.

  • Зачем снова пересчитывать каждый премьер?
    Вы можете рассчитать каждый простой штрих один раз (максимум до максимального числа), а затем просто проверить список или распечатать их все.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню