首页 > 其他分享 >Miller-Rabin 与 Pollard-Rho

Miller-Rabin 与 Pollard-Rho

时间:2024-08-23 21:37:07浏览次数:10  
标签:return Pollard int Miller pmod Rho equiv

1 Miller-Rabin 算法

1.1 引入

Miller-Rabin 的主要作用就是判断一个较大的数是不是质数。

那么根据基础数论中提到过的试除法,我们知道朴素去判断一个数是否是质数的复杂度是 \(O(\sqrt n)\) 的,在 \(n\ge 10^{18}\) 的时候就十分不优了。

而 Miller-Rabin 则是基于费马小定理进行的素性测试,所以首先我们需要知道费马小定理是什么:

当 \(p\) 为质数时,对于任意整数 \(a\),会有 \(a^{p-1}\equiv 1\pmod p\)。

那么如果对于所有的 \(a\),都有 \(a^{p-1}\equiv 1\pmod p\),是否说明 \(p\) 一定是质数呢?事实上不一定,但是其正确率仍然是有的。那我们如果可以利用这种随机性,把正确率不断提高逼近 \(100\%\),是否说明这样的做法也有一定的可取性?

事实上本文介绍的两个算法看上去都是基于随机的,但是都有很高的正确率。

1.2 算法实现

在了解 Miller-Rabin 的实现过程之前,需要了解二次探测定理。

1.2.1 二次探测定理

二次探测定理:若 \(p\) 为素数,且 \(a^2\equiv 1\pmod p\),那么一定有 \(a\equiv \pm1\pmod p\)。

证明:

\(\because a^2\equiv 1\pmod p\)

\(\therefore a^2-1\equiv 0\pmod p\)。

\(\therefore (a+1)(a-1)\equiv 0\pmod p\)。

\(\therefore\) \(a+1\equiv 0\pmod p\) 或 \(a-1\equiv 0\pmod p\)。

1.2.2 算法流程

加入我们当前要判断的数是 \(p\),我们考虑将 \(p-1\) 分解为 \(2^{k}\times t\) 的形式(显然一定可以分解出来)。当 \(p\) 是质数时,一定有 \(a^{2^{k}\times t}\equiv 1\pmod p\)。

那么我们就算出 \(a^t\) 的值,然后不断自乘去累加前面的 \(2^k\) 这一部分的指数。在自乘过程中利用二次探测定理进行判断,如果这一次自乘的数 \(\bmod p=1\),但是上一次的数 \(\bmod p\ne \pm 1\),那么这个数就是合数。同时最后自乘完还要利用费马小定理再判断一次。

那么现在的问题就只在于 \(a\) 的选择,事实上 \(a\) 可以取随机数,也可以取一些较小的质数,但是测试的轮数需要足够,一般取到 \(10\) 左右。

代码如下:

int prim[15] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41};

bool Miller_Rabin(int x) {
	if(x == 2) return 1;
	int t = x - 1, k = 0;
	while(!(t & 1)) t >>= 1, k++;
	for(int i = 1; i <= 13; i++) {
		if(x == prim[i]) return 1;
		int a = qpow(prim[i] % x, t, x), nxt;
		for(int j = 1; j <= k; j++) {
			nxt = a * a % x;
			if(nxt == 1 && a != 1 && a != x - 1) return 0;
			a = nxt;
		}
		if(a != 1) return 0;
	}
	return 1;
}

2 Pollard-Rho 算法

2.1 引入

首先考虑这样一个问题:给定一个正整数 \(N\),找出它的一个非平凡因子(除 \(1\) 和 \(N\) 以外的因子)。

我们在基础数论中提到过可以利用试除法来求解,只需要枚举所有 \([1,\sqrt N]\) 中的数即可,复杂度是 \(O(\sqrt N)\) 的。但是如果 \(N\ge 10^{18}\),这个复杂度无疑是十分差劲的,那么有没有更快的算法呢?

这个时候考虑我们的玄学方法,也就是随机化。我们在 \([1,\sqrt N]\) 里面随便猜一个数,显然其效率是 \(O(1)\) 的,不过正确率就降到了 \(10^{-18}\)​。那么有没有方式提高猜测的正确率呢?

事实上有,而这就是 Pollard-Rho 的基本思想。

2.2 生日悖论

首先我们需要引入一个东西叫做生日悖论。

我们考虑这样一个问题:假如一个房间中有 \(k\) 个人,那么当 \(k\) 达到多少时,其中两个人生日相同(不考虑闰年)的概率可以达到 \(50\%\)?

我们考虑正难则反,显然 \(k\) 个人生日互不相同的概率是 \(P=\dfrac{365}{365}\times\dfrac{364}{365}\times\dfrac{363}{365}\times\cdots\times\dfrac{365-k+1}{365}\)。也就是说生日有重复的概率 \(P'=1-\prod\limits_{i=1}^{k}\dfrac{365-i+1}{365}\)。实际上,当我们令 \(P'\ge \dfrac 12\) 时,可以解得 \(k\) 大概只要取到 \(23\) 以上即可。而当 \(k\) 取到 \(60\) 时,这个概率将会上升至 \(P'\approx 0.9999\)。实际上,假如一年中有 \(n\) 天,只需要 \(\sqrt{n}\) 级别的人数就可以满足要求。

上述数学模型与我们的实际经验严重不符,因此被称作生日悖论。

这个东西给了我们什么启发?考虑生日悖论的实质,实际上就是利用了 “组合随机采样” 的方法,满足答案的组合比单个个体要多,以此来提高正确率。那么怎么将这种思想运用到上面的分解因数中呢?

2.3 算法实现

2.3.1 随机算法的优化

我们利用 “组合随机采样” 的思想,考虑怎样进行组合。显然 \(n\) 与某个数的最大公约数一定是 \(n\) 的因数,也就是 \(\gcd(k,n)\mid n\)。那么我们只要选出一些 \(k\),使得 \(1<\gcd(k,n)<n\),那么就可以求出一个 \(n\) 的非平凡因子了。满足条件的 \(k\) 不少,\(n\) 的任意一个质因子的倍数都是可行的。

那么 Pollard-Rho 算法使用了一个随机函数生成一个序列 \(\{x_i\}\)。我们设 \(f(x)=(x^2+c)\bmod n\),其中 \(c\) 是随机的一个常数。接下来随机选取一个 \(x_1\),然后令 \(x_i=f(x_{i-1})\)。

如果你注意力较高,会发现一件事:由于 \(f\) 函数的取值只有 \(n\) 种,所以总会有一个时刻 \(x\) 数列的生成进入循环,得到相同的结果,如下图所示:

(发现它长得很像一个字母 \(\rho\)​,所以这个算法的名字叫做 Pollard-Rho)

根据生日悖论可知,这个数列中不同值的数量约为 \(O(\sqrt n)\) 个。这个时候我们设 \(m\) 是 \(n\) 的最小质因子,再生成一个数列 \(\{y_i\}\) 满足 \(y_i=x_i\bmod m\)。此时再根据生日悖论可知不同元素的个数约为 \(O(\sqrt m)\le O(n^{\frac 14})\)。于是我们可以在期望 \(O(n^{\frac 14})\) 的时间复杂度之内找出两个值 \(x_i,x_j\),使得 \(x_i \ne x_j\) 且 \(y_i=y_j\),这就说明 \(n \nmid |x_i-x_j|\) 且 \(m\mid |y_i-y_j|\),即 \(\gcd(n,|x_i-x_j|)>1\)。

下面介绍 Pollard-Rho 算法的两种实现方式。

2.3.2 具体流程

2.3.2.1 Floyd 判环

考虑经典的小学奥数:两个人在同一个圆上跑,一快一慢,经过一段时间后两者必会相遇。那我们在 \(x\) 数列上模拟这个过程。设两个指针 \(a,b\),一个以一倍速跑,一个以两倍速跑(即一个是 \(a\leftarrow f(a)\),一个是 \(b\leftarrow f(f(b))\)),这样两者总会相遇,相遇时就出现了环。

然后我们每一次去记录两个 \(a,b\) 对应的 \(\gcd(|a-b|,n)\),看是否符合条件。当出现环的时候,后面就不必再遍历了,此时如果没有找到因子就只能重新调整上述随机函数的参数然后重新分解。

代码如下:

int f(int x, int c, int n) {
	return (mul(x, x, n) + c) % n;
}

int Pollard_Rho(int n, int c) {
	int a, b;
	int x = rnd() % (n - 1) + 1;
	a = f(x, c, n), b = f(f(x, c, n), c, n);
	while(a != b) {
		int d = __gcd(abs(a - b), n);
		if(d > 1 && d < n) return d;
		a = f(a, c, n);
		b = f(f(b, c, n), c, n);
	}
	return n;
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
    //...
	int p = n;
	while(p >= n) {
		p = Pollard_Rho(n, rnd() % (n - 1) + 1);
	}
    //...
	return 0;
}

(实测证明,上述 Floyd 判环代码正确率较下面做法要低)

2.3.2.2 倍增优化

上述过程我们是在同时跑 \(a,b\)。在倍增优化中,我们每一次固定住 \(b\),让 \(a\) 去跑一个固定的长度 \(k\)。每一次求出 \(\gcd(|a-b|,n)\) 并判断。当 \(a\) 跑完之后将 \(b\) 改为 \(a\),同时 \(k\leftarrow 2\times k\),然后不断重复上述过程直到 \(a,b\) 相遇。

代码如下:

int f(int x, int c, int n) {
	return (mul(x, x, n) + c) % n;
}

int Pollard_Rho(int n, int c) {
	int a, b, i = 1, k = 2;
	a = rnd() % (n - 1) + 1, b = a;
	while(1) {
		a = f(a, c, n);
		int d = __gcd(abs(a - b), n);
		if(d > 1 && d < n) return d;
		if(a == b) return n;
		if(++i == k) {
			k <<= 1;
			b = a;
		}
	}
	return n;
}

标签:return,Pollard,int,Miller,pmod,Rho,equiv
From: https://www.cnblogs.com/dzbblog/p/18377127

相关文章

  • 从龟速乘到 $Miller-Rabin$ 算法(数论算法总结)
    发现自己竟然菜到不太会龟速乘,所以把\(Miller-Rabin\)算法所需要用到的算法全学了一遍……龟速乘龟速乘是一种\(O(\logn)\)的乘法计算方法。考虑有时普通乘法取模会爆\(long\long\),因此我们考虑用类似快速幂的方式进行乘法运算。intmul(intx,inty,intc){ x%=c,y%=......
  • Pollard-Rho的一些应用
    P4718https://www.luogu.com.cn/problem/P4718要求找最大的素因子,考虑可能出现在因子的因子中,所以需要递归i64max_prime(i64n){if(isp(n)){returnn;}i64mx{std::numeric_limits<i64>::min()};while(n!=1){autodiv{findDiv(n)};mx......
  • Miller-Rabin 和 Pollard-Rho 小记
    Miller-Rabin可以帮助我们快速判断一个大数是不是质数,现在已经有了确定性算法。在\(2^{64}\)范围内,我们可以快速地进行确定性判素。二次校验定理:若\(p\)为奇质数,则\(a^x\equiv1\pmodp\)的解为\(x=±1\)。我们有这样的流程:令\(d=p-1\),然后不断检验\(a^d\)......
  • Miller Rabin算法判定质数(OI向)
    前言:本篇不太适合那些对数学证明要求严格的Oier,然后本人也是蒟蒻,主要写给自己回顾用的MillerRabin算法能快速的判断一个数是否为质数,作为一个数学算法它具有一定的玄学成分,但是在OI中通过一些手段可以使其达到100%正确。先让我们对比一下一般算法书教的2种关于质......
  • Rhodamine B PEG Rhodamine B,罗丹明聚乙二醇罗丹明,分子量:1k,2k,3.4k,5k
    西安凯新生物作为高分子PEG供应商WMJ为大家介绍(RhodamineBPEGRhodamineB),试剂仅用于科学研究,不可用于人类,非药用,非食用。分子量:1k,2k,3.4k,5k,10k,20k(可按需定制)中文名称:罗丹明聚乙二醇罗丹明英文名称:RhodamineBPEGRhodamineB结构式:物理性质:外观特点:固体、粉末端......
  • 学习笔记:Miller-Rabin 与 Pollard-Rho
    Miller_Rabin首先考虑方程\(x^2\equiv1\pmodn\)。可以写成\((x+1)(x-1)=kn\)。当\(n\)为素数时,只可能\(n\midx+1\)或\(n\midx-1\),反之合数不满足。得到结论:在模素数意义下,一个数的平方等于\(1\)当且仅当这个数同余于\(1\)或\(-1\)。我们知道,......
  • 中国移动光猫Fiberhome HG6145F获取超级管理员密码和解决第四号口不能用的问题
    第一步获取光猫MAC地址你看光猫背后就行了,如果没有,就用命令:arp-a192.168.1.1第二步开启telnet访问地址:http://192.168.1.1/cgi-bin/telnetenable.cgi?telnetenable=1&key=你的Mac地址,要求全大写如果成功,网页会显示:telnet开启第三步进入telnet地址还是在电脑用cmd输入:t......
  • 【模板】分解质因数 Pollard-Rho
    参见洛谷模板题题解,这里只有代码实现。一些强数据参考(输出了最大质因子)79223372036854775783Prime9223371994482243049303700049392232532901085832072097143214748364822147483647Prime21471175694633721417005691289#include<bits/stdc++.h>usingnamespace......
  • Miller–Rabin 素性测试
    Miller–Rabin素性测试(Miller–Rabinprimalitytest)是进阶的素数判定方法。它是由Miller和Rabin二人根据费马小定理的逆定理(费马测试)优化得到的。因为和许多类似算法一样,它是使用伪素数的概率性测试,我们必须使用慢得多的确定性算法来保证素性。然而,实际上没有已知的数字通过......
  • 52 Things: Number 35: Give the rough idea of Pollard rho, Pollard "kangaroo" and
    52Things:Number35:GivetheroughideaofPollardrho,Pollard"kangaroo"andparallelPollardrhoattacksonECDLP.52件事:第35件:大致了解Pollardrho、Pollard“袋鼠”和平行的Pollardrho对ECDLP的攻击。 Thisisthelatestinaseriesofblogpoststoadd......