素数计算,判断大数是否是素数。如10000!+(随机数)(200分)

  • 主题发起人 主题发起人 ybangl
  • 开始时间 开始时间
Y

ybangl

Unregistered / Unconfirmed
GUEST, unregistred user!
判断大数是否是素数。如10000!+(随机数)是否是素数
 
http://www.delphiforfun.org/Programs/big_factorials.htm
 
我知道怎样算10000!
怎样判断大数是否是素数?如10000!+(随机数)是否是素数?
继续,作为一个课题,大家动动脑筋吧!看能不能找到快的办法,如果不能,请给出不能的严格证明。
 
VAR
tmp,num:longint;
{Long Integer signed 32-bit (31-bit on each side)}
j,k:byte;
{ Slow? Fast? way to find primes, dividing by odd numbers }
Function IsPrime(num:longint):boolean;
Var
tmp:boolean;
j:longint;
begin
tmp:=true;
if num mod 2=0 then
tmp:=false;
for j:=3 to round(sqrt(num))do
if odd(j) then
if num mod j=0 then
tmp:=false;
if num=2 then
tmp:=true;
IsPrime:=tmp;
end;

begin
tmp:=2;
{2^1}
writeln('Perfect numbers...');
for j:=2 to 31do
begin
tmp:=tmp*2;
{Raise 2 to another power}
if IsPrime(j) then
begin
num:=tmp-1;
if IsPrime(num) then
begin
num:=num*(tmp div 2);
writeln(num:1,' is perfect');
{Ignore negatives}
end;
end;
end;
end.
 
楼上的兄台,用您的这种算法即使宇宙的生命结束了也不会得出结果的...
现在的随机素数发生器都是用费马测试来检测整数是否为的素数的。
to ybangl:
10000!——需要那么大吗?我记得现在比较强的大整数分解算法也只能对付数百位的整数,
而10000!有35660位——似乎难以搞定吧...

刚找到一个数论算法包,其中的素性测试代码如下:
/*********************************************
Miller_Rabin随机素数测试算法
说明:这种算法可以快速地测试一个数是否
满足素数的必要条件,但不是充分条件。不
过也可以用它来测试素数,出错概率很小,
对于任意奇数n>2和正整数s,该算法出错概率
至多为2^(-s),因此,增大s可以减小出错概
率,一般取s=50就足够了。
*********************************************/
int Witness(int a,int n)
{
int i,d=1,x;
for (i=ceil(log((float)n-1)/log(2.0))-1;i>=0;i--)
{ x=d;
d=(d*d)%n;
if ((d==1)&&(x!=1)&&(x!=n-1)) return 1;
if (((n-1)&amp;(1<<i))>0) d=(d*a)%n;
}
return (d==1?0:1);
}
int Miller_Rabin(int n,int s)
{
int j,a;
for (j=0;j<s;j++)
{ a=rand()*(n-2)/RAND_MAX+1;
if (Witness(a,n)) return 0;
}
return 1;
}
( http://algorithm.myrice.com/resources/code_center/algorithm/number_theory/number_theory_c.htm )
 
找到一篇文章:
http://student.zjzkb.edu.cn/course_ware/data_structure/web/jingcaiwenzhang/wenzhang14.htm

如何产生素数
Solovag-Strasson
Robert Solovag和Volker Strasson开发了一种概率的基本测试算法。这个算法使用了雅可
比函数来测试p是否为素数:
(1) 选择一个小于p的随机数a。
(2) 如果GCD(a,p)<>1,那么p通不过测试,它是合数。
(3) 计算j=a^(p-1)/2 mod p。
(4) 计算雅可比符号J(a,p)。
(5) 如果j<>J(a,p),那么p肯定不是素数。
(6) 如果j=J(a,p),那麽p不是素数的可能性值多是50%
数a被称为一个证据,如果a不能确定p,p肯定不是素数。如果p是合数。随机数a是证据的
概率不小于50%。对a选择t个不同的随机值,重复t次这种测试。p通过所有t次测试后,它是
合数的可能性不超过1/2^t。
Lehmann
另一种更简单的测试是由Lehmann独自研究的。下面是它的测试算法:
(1) 选择一个小于p的随机数a。
(2) 计算a^(p-1)/2 mod p
(3) 如果a^(p-1)/2<>1或-1(mod p),那么p肯定不是素数。
(4) 如果a^(p-1)/2=1或-1(mod p),那麽p不是素数的可能性值多是50%
同样,重复t次,那麽p可能是素数所冒的错误风险不超过1/2^t。
Rabin-Miller
这是个很容易且广泛使用的简单算法,它基于Gary Miller的部分象法,有Michael Rabin
发展。事实上,这是在NIST的DSS建议中推荐的算法的一个简化版。
首先选择一个代测的随机数p,计算b,b是2整除p-1的次数。然后计算m,使得n=1+(2^b)m。
(1) 选择一个小于p的随机数a。
(2) 设j=0且z=a^m mod p
(3) 如果z=1或z=p-1,那麽p通过测试,可能使素数
(4) 如果j>0且z=1, 那麽p不是素数
(5) 设j=j+1。如果j<b且z<>p-1,设z=z^2 mod p,然后回到(4)。如果z=p-1,那麽p通过
测试,可能为素数。
(6) 如果j=b 且z<>p-1,不是素数
这个测试较前一个速度快。数a被当成证据的概率为75%。这意味着当迭代次数为t时,它
产生一个假的素数所花费的时间不超过1/4^t。实际上,对大多数随机数,几乎99.99%肯定
a是证据。
实际考虑:
在实际算法,产生素数是很快的。
(1) 产生一个n-位的随机数p
(2) 设高位和低位为1(设高位是为了保证位数,设低位是为了保证位奇数)
(3) 检查以确保p不能被任何小素数整除:如3,5,7,11等等。有效的方法是测试小于
2000的素数。使用字轮方法更快
(4) 对某随机数a运行Rabin-Miller检测,如果p通过,则另外产生一个随机数a,在测试。
选取较小的a值,以保证速度。做5次 Rabin-Miller测试如果p在其中失败,从新产生p,再
测试。

在Sparc II上实现: 2 .8秒产生一个256位的素数
24.0秒产生一个512位的素数
2分钟产生一个768位的素数
5.1分钟产生一个1024位的素数 //********

请注意:“5.1分钟产生一个1024位的素数”——那么,需要几年才能产生一个3万多位的
素数呢?
 
素数的比例越是随着数字的增加而减少的,要想找到素数是越来越难。
要求精确的确定大素数:
1.首先要写大整数的乘法和除法
2.要建立巨大的素数表以供求更大的素数调用。
以上两个条件就使得您的存储空间---内存加硬盘不够使用。
然后是时间的考虑。数量巨大的乘除法运算将使得时间上无法实现。[:)]
另外,问题在于:确定如此巨大的素数有什么实际的意义?
 
继续,作为一个课题,大家动动脑筋吧!
 
继续,作为一个课题,大家动动脑筋吧!看能不能找到快的办法,如果不能,请给出不能的严格证明。
 
找大于10000!的大素数倒不难,难就难在如何判断一个大数是否素数……复杂度太高了
 
怎样证明你找的数是素数呢?
 
还记得欧氏证明不存在最大素数的推理吗?就是它
 
证明不存在最大素数的方法:
假设N是最大的素数,那么 M = 2*3*4...*N+1 不能被1~N之间的所有素数整除,
因此M要么是素数,要么能被一个大与N的素数整除。矛盾!故N不存在。即不存在最大素数。
我现在只知道判断素数只能用定义(筛法)来做,不晓得能不能找到更好的办法。
估计是没有。因此最好的算法也就只能用动态规划法(我上面讲的)。
要是能找到更好的方法,请帖出来,谢谢![:)]
 
所以我说,找一个更大的素数不难,但是证明一个数是不是素数就比较难了。
比如我用筛法将从1~80000的素数筛选出来不难吧?那么我只要把它们全都乘在一起再+1,这个数就一定是素数了。
另,你引用的那段证明有一个错误,就是几个被乘数必须全都是素数,而且不能遗漏(必须从2开始乘),否则得出来的数比一定是素数,比如2*7+1=15就不是。
 
to Traveller
另,你引用的那段证明有一个错误,就是几个被乘数必须[red]全都是素数[/red],而且不能遗漏(必须从2开始乘),否则得出来的数比一定是素数,比如2*7+1=15就不是。
DarwinZhang的证明没有错,只要几个被乘数包含了所有小于等于N的素数就可以了。
 
非常精彩,我一定给你们多加点分
 
“只要几个被乘数包含了所有小于等于N的素数就可以了”
不对吧,欧氏不是这样证明的。如果那样岂不是说N!+1都是素数?!显然这是不成立的,比如2*3*4+1=25,显然不是素数。
 
如果你指望通过普通的方法检测(成千上万位的)大数的素性——在时间上是绝对不现实
的。因为一个数百位的大数开方之后仍然有相当多的小于它的质数(记得质数分布密度公式
吗?—— ln(x)/x。我的微积分已经忘完了,有兴趣的同志可以自己积分一下,看看3万位
的大数可能被多少个素数整除),正是因为时间不允许用普通的方法来证明一个大数肯定是
素数,先人们才会开发出费马测试等基于概率的素性检测方法——即便这样,生成上千位(
我怀疑这里的“位”是二进制的)已经非常之慢,楼主的要求已经大大超过了现代计算机的
计算能力。
另外,关于欧氏的“素数无限”的证明过程,我记得是这样的:
假设素数的个数是有限的——我们假设素数总共有n个,分别为K1,K2,K3,...,Kn。好的,
我们可以生成一个新的数: S=K1*K2*K3*...*Kn+1 ——显然,S不能被任何素数(Ki)整除—
—所以S必然是素数,但显然S不在{K1,K2,K3,...Kn}之中——与题设(只有K1,K2,...Kn是
素数)矛盾——假设不成立。因此,素数有无限多个。
——欧氏的S是基于所有素数的乘积的,当然不会被任何一个素数整除。楼上同志们想用
有限个素数按照他的方法生成新素数,显然是不可行的。
 
sorry,想了一下,我的推理看来有错误,欧氏是在假设存在最大素数的条件下进行的归谬,不能照搬来做素数的计算公式,收回我的话 :-(
 
后退
顶部