Effective prime factorization for large numbers

I worked on a small problem when I need to compute 18-digit numbers into their corresponding factorization. Everything compiles, and everything works very well, given that it really works, but I try to reduce the time it takes to complete simple factorization. I implemented recursion and threads, but I think I may need help in understanding the possible algorithms for calculating a large number.

Each time I run it on 4 numbers that I previously made, it takes about 10 seconds. I would like to reduce this to 0.06 seconds if there are any ideas.

I noticed several algorithms, such as the "Sieve of Eratosthenes" and making a list of all primes before calculating. I'm just wondering if anyone can figure this out. For example, I am having trouble understanding how to incorporate Sieve of Eratosthenes into my program, or if it would even be a good idea. Any and all pointers on how to approach this better will be really helpful!

Here is my code:

#include <iostream>
#include <thread>
#include <vector>
#include <chrono>

using namespace std;
using namespace std::chrono;

vector<thread> threads;
vector<long long> inputVector;
bool developer = false; 
vector<unsigned long long> factor_base;
vector<long long> primeVector;

class PrimeNumber
{
    long long initValue;        // the number being prime factored
    vector<long long> factors;  // all of the factor values
public:
    void setInitValue(long long n)
    {
        initValue = n;
    }
    void addToVector(long long m)
    {
        factors.push_back(m);
    }
    void setVector(vector<long long> m)
    {
        factors = m;
    }
    long long getInitValue()
    {
        return initValue;
    }
    vector<long long> getVector()
    {
        return factors;
    }
};

vector<PrimeNumber> primes;

// find primes recursively and have them returned in vectors
vector<long long> getPrimes(long long n, vector<long long> vec)
{
    double sqrt_of_n = sqrt(n);

    for (int i = 2; i <= sqrt_of_n; i++)
    {
        if (n % i == 0) 
        {
            return vec.push_back(i), getPrimes(n / i, vec); //cause recursion
        }
    }

    // pick up the last prime factorization number
    vec.push_back(n);

    //return the finished vector
    return vec;
}

void getUserInput()
{
    long long input = -1;
    cout << "Enter all of the numbers to find their prime factors. Enter 0 to compute" << endl;
    do
    {
        cin >> input;
        if (input == 0)
        {
            break;
        }
        inputVector.push_back(input);
    } while (input != 0);
}

int main() 
{

    vector<long long> temp1;   // empty vector
    vector<long long> result1; // temp vector

    if (developer == false)
    {
        getUserInput();
    }
    else
    {
        cout << "developer mode active" << endl;
        long long a1 = 771895004973090566;
        long long b1 = 788380500764597944;
        long long a2 = 100020000004324000;
        long long b2 = 200023423420000000;
        inputVector.push_back(a1);
        inputVector.push_back(b2);
        inputVector.push_back(b1);
        inputVector.push_back(a2);
    }

    high_resolution_clock::time_point time1 = high_resolution_clock::now();

    // give each thread a number to comput within the recursive function
    for (int i = 0; i < inputVector.size(); i++)
    {   
        PrimeNumber prime;
        prime.setInitValue(inputVector.at(i));
        threads.push_back(thread([&]{
            prime.setVector(result1 = getPrimes(inputVector.at(i), temp1));
            primes.push_back(prime);
        }));
    }

    // allow all of the threads to join back together.
    for (auto& th : threads)
    {
        cout << th.get_id() << endl;
        th.join();
    }

    high_resolution_clock::time_point time2 = high_resolution_clock::now();

    // print all of the information
    for (int i = 0; i < primes.size(); i++)
    {
        vector<long long> temp = primes.at(i).getVector();

        for (int m = 0; m < temp.size(); m++)
        {
            cout << temp.at(m) << " ";
        }
        cout << endl;
    }

    cout << endl;

    // so the running time
    auto duration = duration_cast<microseconds>(time2 - time1).count();

    cout << "Duration: " << (duration / 1000000.0) << endl;

    return 0;
}
+4
source share
5 answers

. n 2 ^ 64 : , , rho, . - O (sqrt (n)), rho - O (sqrt (sqrt (n))), . 2 ^ 64 sqrt (n) = 2 ^ 32, sqrt (sqrt (n)) = 2 ^ 16, . , .

++ , Python. , , . rho, .

+9

, Eratosthenes , . , .

, , L3. , 2, 3 5 , 8- 30 , 1 1, 7, 11, 13, 17, 19, 23 29 30 - - 10 ^ 9 ~ 32 - 10 ^ 9/(30 * 1024 * 1024). -, 2, ~ 60 - 10 ^ 9/(2 * 8 * 1024 * 1024).

, 10 ^ 9 sqrt (10 ^ 9) - 1,055 , 10 ^ 9.

FWIW, , AMD Phenom II x6 1090T (8 L3), 10 ^ 9:

  1. 1 core,   1 segment    3.260 seconds elapsed
  2. 5 cores,  1 segment    1.830 seconds elapsed
  3. 1 core,   8 segments   1.800 seconds elapsed
  4. 5 cores, 40 segments   0.370 seconds elapsed

"" . ~ 32 , , , 4 L3.

. 0,5 ! , 0,270 , (4) .

FWIW, - 0.240 (4) - , 7, 11, 13 17. 17017 .

, 0,06 ... , !

+2

:

if (n % 2) {
    return vec.push_back(i), getPrimes(n / i, vec);
}

for (int i = 3; i <= sqrt_of_n; i += 2)
{
    if (n % i == 0) 
    {
        return vec.push_back(i), getPrimes(n / i, vec); //cause recursion
    }
}

. , 3, . , 4, 6, 8,... 2 . , .

N, <= sqrt (N). 18- 1e9, 98 2e9 100 . 8 (int64_t), 100 800 . SPOJ β„–2, Prime Generator.

, 32- int, - Eratostenes. , , sqrt (N), N, 64- , , 32- .

+1
for(int i  = 2; i * i <= n; ++i) //no sqrt, please
{
    while(n%i == 0) //while, not if
    {
         factors.push_back(i);
         n/=i;
    }
}
if(n != 1)
{
    factors.push_back(n);
}

, , . - sqrt N. 18- , . , , , 10 .

+1

The integer factorization algorithm is so simple that it can even be implemented on abacus.

void start()
{ 
   int a=4252361;    //  integer to factorize
   int b=1,  c,  d=a-1;  

   while ((a > b) && (d != b))
  {
    if (d > b)
     {
       c=c+b;
       a=a-1;
       d=a-c-1;
     }
    if (d < b)
     {
       c=b-d;
       b=b+1;
       a=a-1;
       d=a-c-1;
     }         
  }
    if ((d == b)&&(a > b)) 
  Alert ("a = ",  a-1,  " * ", b+1); 

    if ((d < b)&&(a <= b)) 
  Alert ("a  is a prime");

  return;
}

The algorithm was compiled by me, Viktor Milyaev, born on July 26, 1950. It is written in MQL4 15.12. 2017. E-mail: tenfacet27@gmail.com

-2
source

All Articles