Answer the question
In order to leave comments, you need to log in
Is the algorithm for determining the non-simplicity of a number with 3 operations useful?
I studied one theory, it turned out to be true in 75-80% of cases. That is, for any number with a probability of 75%, the algorithm says that it is not prime, while only 3 mathematical operations are performed, no cycles, etc. The algorithm remains true with the same probability for any number of characters, checked in a very wide range. It can speed up other algorithms for checking for simplicity, that is, before checking with complex algorithms, you can run it and say with 75% that the number is not prime and do not check further. The question is, does anyone need such a miracle, or is there no use with such an error?
The algorithm is simple, there are certain numbers, when divided by which the remainder of the division will be a prime number in 75% of cases, so if the remainder of the division turned out to be not a prime number, we can assume that it is composite.
class MayBePrime
{
static bool[] charr = null;
static int prime = 30030;//30030 для быстрого старта, ниже точность. Произведение первых простых чисел
static public bool isMayBePrime(System.Numerics.BigInteger x)
{
if (charr == null)
{
charr = new bool[prime];
for (int i = 0; i < prime; i++)
{
if (NOD(prime, i) == 1)
{
charr[i] = true;
}
else
{
charr[i] = false;
}
}
}
BigInteger n = x % prime;
int n2 = 0;
n2 = (int)n;
if (charr[n2])
{
return true;
}
else
{
return false;
}
}
static public int NOD(int a, int b)
{
if (a == 0) return b;
if (b == 0) return a;
if (a == b) return a;
if (a == 1 || b == 1) return 1;
if ((a % 2 == 0) && (b % 2 == 0)) return 2 * NOD(a / 2, b / 2);
if ((a % 2 == 0) && (b % 2 != 0)) return NOD(a / 2, b);
if ((a % 2 != 0) && (b % 2 == 0)) return NOD(a, b / 2);
return NOD(b, Math.Abs(a - b));
}
}
Answer the question
In order to leave comments, you need to log in
I hope that the remainder is still taken from division by 390, and not by 389 - otherwise there is no point in the code at all.
So, we have 77 primes less than 390. Four of them - 2,3,5,13 - are nothing more than garbage, giving extra algorithm runs. Indeed, if x%390==3, then x is divisible by 3, which means it is composite. The remaining 73 numbers are fine.
It turns out such a picture. For a prime x, the value x%390 is some number coprime to 390. Moreover, these remainders are more or less evenly distributed (in the picture they look like red bars). There are 96 of these remainders
. If x is a prime number, then with a probability of 73/96 the remainder will be a prime number, and the algorithm will honestly say "rather, a prime number." With a probability of 23/96 - those same 25% - the remainder will be composite, and the algorithm will make a mistake.
If x is composite, then the probability that the number will be declared "rather prime" will be equal to 77/390-1/ln(x) (the first term is the probability that the remainder turned out to be prime, and the second is the proportion of prime numbers in the vicinity of x ).
You can easily get rid of the error of the first type: for this, you need to put in the charr array not prime numbers, but numbers coprime with 390. Then if the algorithm says "composite", then it is.
It was possible to take N=30030=2*3*5*7*11*13 instead of 390. If the array is filled with numbers relatively prime to N, then 4 out of 5 numbers will be screened out as composite numbers, and there will be no false screening of prime numbers at all.
An arbitrarily chosen number, not exceeding 10^5, with a probability of 90% composite. Further more.
However, open your way.
UPDATE
def main(*mods):
lo = 10 ** 5
hi = 10 ** 9
sieve = [1] * hi
sieve[0] = sieve[1] = 0
for i in range(int(hi ** 0.5) + 1):
if sieve[i]:
for j in range(i * i, hi, i):
sieve[j] = 0
primes = sum(sieve[lo:])
for mod in mods:
counter = [0] * 4
for i in range(lo, hi):
counter[sieve[i] * 2 + sieve[i % mod]] += 1
print('\n{:>17n}\nprime \ check 0 1\n'
' 0 {:7.3f} {:7.3f}\n'
' 1 {:7.3f} {:7.3f}\n'.format(
mod, *[float(i) / primes for i in counter]))
main(30029, 30030, 30047)
30029
prime \ check 0 1
0 16.650 2.019
1 0.892 0.108
30030
prime \ check 0 1
0 17.104 1.564
1 0.437 0.563
30047
prime \ check 0 1
0 16.650 2.018
1 0.892 0.108
from itertools import cycle
def MillerRabin(n):
return True # допустим, здесь реализован тест Рабина-Миллера
def getprime(startsfrom):
primes = (2, 3, 5, 7, 11, 13)
mod = 1
for p in primes:
mod *= p # итого mod = 30030
steps, x0 = [], mod - 1
for x in range(mod, x0 + mod + 1):
if all(x % p for p in primes):
steps.append(x - x0)
x0 = x
print(len(steps) / mod) # 0.1918 - мы отсеяли 4/5 чисел
# входного потока, не потеряв ни единого простого.
# по итогу имеем те же 25% простых во входном потоке
# на интервале 10^5..10^9
n = startsfrom // mod * mod - 1
for step in cycle(steps):
n += step
if n > startsfrom and MillerRabin(n):
return n
print(getprime(10 ** 500))
# 10^500+961
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question