-4

My prime pattern

Primes are really strange... I created this simple pattern out of boredom. I haven't seen any of similarity online. As you see, the picture has lines of absence depending on the scale you choose, this is ranging from values 1 to 1000000

I intend on going from values 1 - 25,000,000 and perhaps 1 - 10,000,000,000

Perhaps the use of sieve techniques would help, but I need an adequate java implementation, I use the classic prime checker consisting of 2 for-loops which really chows time.

EDIT: here is a sample of my code

 boolean checkPrime(long a)
 {
 long count = 0L;
    for(long op = 1;op<=a;op++)  
            if(a%op==0)
                     count++;

  return count ==2;
 }

Update: I found a simple optimisation measure for my code

 boolean checkPrime(long a)
 {
 long count = 0L;
    for(long op = 1;op<=a;op++)  
            if(a%op==0)
                      {
                       count++;
                               if(count>2)break; //here it is
                      }

  return count ==2;
 }

Code seems to run x10 faster

I finally chose to create this and stick with it.

package superprime;
public class SuperPrime {
    static java.util.List primes = new java.util.ArrayList<Long>();
    public static void main(String[] args) {
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        long start = System.currentTimeMillis();
       primes.add(2);
       boolean flag = true;
       long u =primes.size();long wow;double val;
    for(long e = 3L; e<10000000;e=e+2){
        flag = true;
        for( wow = 0;(wow< u)&&flag;wow++){
            if(e%(Long.parseLong(primes.get((int)wow)+""))==0)
           flag=false;

        }
        if(flag)primes.add(e);
        val = Double.parseDouble(primes.get((int)u)+"");
        if((val == Math.sqrt(e+1))||(val == Math.sqrt(e+2)))u++;
   // if(e%250000==0)System.out.println((System.currentTimeMillis()-start)/1000.0+" @ "+e);
    }long end =System.currentTimeMillis();
     System.out.println(""+(end-start)/1000.0);
     wow = 1;
for(Object h : primes)System.out.println(++wow+"\t"+(Long.parseLong((h)+"")));

    }

}
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • check wikipedia for better algorithms – Harry Blargle May 11 '14 at 19:37
  • I'm not sure I see a question here... – Oliver Charlesworth May 11 '14 at 19:37
  • I have attempted to compile results from my interpretation of the Wikipedia pages and I fail dismally. I am only a High School student. – Richard Kenneth Niescior May 11 '14 at 19:41
  • You have asked us to improve your algorithm for prime checking. You failed to communicate what your current algorithm is. The picture doesn't help with that. – candied_orange May 11 '14 at 19:44
  • Try to make similar picture but with numbers located on a spiral – Egor Skriptunoff May 11 '14 at 19:45
  • This question appears to be off topic because [so] isn't a search engine or code writing service. – Bernhard Barker May 11 '14 at 19:47
  • 1
    Use the Sieve of Eratosthenes. Since a clear lower bound for this application is O(N), it is almost optimal (apart from a `log log N` factor) – Niklas B. May 11 '14 at 19:49
  • That is exactly what I can not wrap my head around. In South African mathematics education, the high schools do not cover log functions extensively if at all. – Richard Kenneth Niescior May 11 '14 at 19:58
  • 1
    @RichardKennethNiescior you mention that you failed to implement some algorithms from Wikipedia. Why don't you choose one of them and ask a question specifically about your difficulty there. Also, follow Niklas advice and use the Sieve of Erasthotenes. Look it up somewhere. The algorithm is reasonably easy to understand. Niklas's comment was about the mathematical analysis of the computational complexity of the algorithm (related to the time it takes to execute). Also, please try to be more clear as to what you're actually asking in the future =). – Rafael Almeida May 11 '14 at 20:49

2 Answers2

2

Code you presented is makeing a operations for every a. It is simple way to improve it:

boolean checkPrime(long a)
 {
 long count = 0L;
 for(long op = 2;op*op<=a;op++)  
        if(a%op==0)
                 return false;

  return true;
 }

Now it makes only sqrt(a) operations and always gives right answer. For beter execution times are randomised algorithms like Rabin-Milers algorithm: http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

I include mine implementation in c++ of Rabin-Milers algorithm.

#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;

const int losowania=20;

long long pote(long long x,long long k,long long m)//this function is counting (x^k)mod m
{
if(k==1)
{
    return x%m;
}
if(k%2==0)
{
    long long a=pote(x,k/2,m);
    return ((__int128_t)((__int128_t)a*(__int128_t)a)%(__int128_t)m);
}
else
{
    long long a=pote(x,k-1,m);
    return ((__int128_t)((__int128_t)a*(__int128_t)x)%(__int128_t)m);
}
}

bool Rabin_Miler(long long p,long long x)
{

if(pote(x,p-1,p)!=1)
{
    return false;
}
long long wyk=(p-1);
while(wyk%2==0)
{
    wyk/=2;
}
long long teraz=pote(x,wyk,p);
if(teraz==1)
{
    return true;
}
while(teraz!=1&&teraz!=p-1)
{
    teraz=(__int128_t)((__int128_t) teraz*(__int128_t)teraz)%(__int128_t)p;
}
if(teraz==1)
{
    return false;
}
else
{
    return true;
}
}

bool is_prime(long long p)
{
srand(100);
    for(int i=0;i<losowania;i++)
    {
        if(!Rabin_Miler(p,(rand()%(p-1))+1))
        {
            return false;
            break;
        }
    }
return true;
}
Kamil
  • 170
  • 3
  • 9
  • 2
    Prime testing will still be much too slow for billions of numbers, no matter what algorithm you use. A sieve is the way to go here – Niklas B. May 11 '14 at 21:11
1

If you want to find every prime, then you can use a version of erathmus' sieve to generate the first 1000 or so, and then only check the list of prior primes, as they are the only meaningful factors by the fundamental theorem of algebra. If you want to find all the primes this is almost certainly faster than using a general number field sieve, which are designed to try to factor large numbers efficiently when you dont have a list of primes. Here is somthing that I wrote for Euler Project Number 7. It has two functions, one which uses erathmus' sieve to find all the primes up to 1000, then it uses the list of primes as an input to sequentially work of the next number which is prime via trial division of the list of primes.

public class NthPrime {

/**
 * @param args
 */
public static void main(String[] args) 
{
    int N = 10001;
    long startTime = System.currentTimeMillis();
    ArrayList<BigInteger> firstPrimes = primes(1000);
    System.out.println("The "+N +"th Prime is: " + Nthprime(firstPrimes, N));
    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    System.out.println(firstPrimes.toString());
    System.out.println(elapsedTime);

}

public static BigInteger Nthprime(ArrayList<BigInteger> primes, int N)
{
    if(N < primes.size())
    {

        return primes.get(N-1);

    }



    BigInteger start = primes.get(primes.size()-1);
    boolean bool = true;
    BigInteger ZERO = new BigInteger("0");
    BigInteger ONE = new BigInteger("1");
    BigInteger j = new BigInteger("1");
    while(bool)
    {
        boolean hasfactor = false;
        for(int i=0; i<primes.size(); i++)
        {

            BigInteger Q = start.add(j);
            BigInteger remainder = Q.mod(primes.get(i));

            if(remainder.equals(ZERO))
            {
                hasfactor = true;
                break;
            }
        }

        if(!hasfactor)
        {
            primes.add(start.add(j));

        }

        if(primes.size() == N)
        {
            bool = false;
        }

        j = j.add(ONE);
    }

    return primes.get(primes.size()-1);

}


public static ArrayList<BigInteger> primes(int N)
{
    boolean[] primes = new boolean[N+1];


    for(int j = 0; j<N+1; j++)
    {
        primes[j] = true;
    }
    int i = 2;
    while(i < N+1)
    {
     if(primes[i])
        {
            int j = 2*i;
            while(j<N+1)
            {
                primes[j] = false;
                j = j+i;

            }
        }
     i++;
    }
    ArrayList<BigInteger> allprimes = new ArrayList<BigInteger>();
    for(i=2; i<N+1; i++)
    {
        if(primes[i])
        {
            allprimes.add(new BigInteger((new Integer(i)).toString()));
        }
    }

    return allprimes;


}

}

phil_20686
  • 4,000
  • 21
  • 38
  • 1
    PS: You could also consider just looking up the list of primes on the prime project.... – phil_20686 May 12 '14 at 13:39
  • 1
    Also, erathmus's sieve is quicker so in the sample code you can up the value in primes. It will vind all primes less than 1,000,000 in less than 100ms on my machine. Its limited by the maximum size of int though as it depends on an array, so wont go past 2^32-1. That might not be a problem for you. Its complexity is n*log(log(n)), so its worse than linear but not my much. – phil_20686 May 12 '14 at 13:54
  • The sieve for all primes below one billion takes me 10 seconds. By using a `long[]` as a bitmap and omitting even numbers, you can go up to 2.7e11, which may take a few gigs and a few hours maybe. – maaartinus May 13 '14 at 17:27