zoukankan      html  css  js  c++  java
  • [学习笔记]Pollard Rho算法

    问题

    \(N \in N^{+}\),试快速处理出其一个因数。

    生日悖论

    考虑把每个人的生日写作一个正整数,才能使其中两个人生日相同的概率大于\(50%\)

    假设一年中有 \(n\) 天,房间 \(k\) 人,用整数\(1,2,....,k\)对这些人进行编号,假定每个人的生日均匀分布于\(n\)天之中,且两个人的生日相互独立。

    \(k\)个人生日互不相同为事件\(A\),则事件\(A\)的概率为
    \(P(A) = \prod_{i = 1} ^ k \frac{n - i + 1}{n}\)

    那么知\(P(A) \leq \frac{1}{2}\)

    \(1 + x \leq e ^ x\)

    \(P(A) \leq \prod_{i = 1}^k e^{\frac{1 - i}{e}} = e^{-\frac{k * (k - 1)}{2n}}\leq \frac{1}{2}\)

    若一年有\(n\)天,其房间里有\(\sqrt n\)个人时满足条件。

    构造伪随机函数

    我们通过\(f(x) = (x^2 + c) \ mod\ n\)来生成一个随机数序列\(x_i\),其中\(c = rand()\),是一个随机的常数。

    随机取\(x_1\),令\(x_2 = f(x_1),x_3 = f(x_2) .... x_i = f(x_{i - 1}])\)

    优化随机算法

    最大公约数一定是某个数的约数,即\(\forall k \in N^{+},gcd(k,n) | n\),只要选适当的 \(k\) 使得 \(1 < gcd(k,n) < n\)就可以求得一个约数 \(gcd(k,n)\)

    将生日悖论应用到随机算法中,伪随机数列中不同值的数量的约为\(O(\sqrt n)\)个,设\(m\)\(n\)的最小的非平凡银子,显然有\(m\leq\sqrt n\)则有 \(y_i = x_i (mod\ m)\)

    那么有\(y_{i + 1} = x_{i + 1}\ mod\ m = y_i ^ 2 + c (\ mod\ m)\)

    所以其不同的数有\(O(\sqrt m) \leq O(n^{\frac{1}{4}})\)

    如果有\(x_i \neq x_j \land y_i = y_j\),这意味着\(n \nmid |x_i - x_j| \land m | |x_i - x_j|\),所以我们可以通过\(gcd(n,|x_i - x_j|)\)获得\(n\)的一个平凡因子。

    时间复杂度分析

    \(O(\sqrt m)\)

    实现

    Floyd判环

    \(a = f(1),b = f(f(1))\),每一次更新为\(a = f(a),b = f(f(b))\),只要检查在更新过程\(a,b\)是否等于环,每次检查\(gcd(|x_i - x_j|,n)\)是否满足条件。

    Floyd判环
    ll Pollard _Rho(ll n){
    	ll c = rand() % (n - 1) + 1;
    	ll t = f(0,c,n);
    	ll r = f(f(0,c,n),c,n);
    	while(t != r){
    		ll d = gcd(abs(t - r),n);
    		if(d > 1)return d;
    		t = f(t,c,n);
    		r = f(f(r,c,n),c,n);
    	}
    }
    

    倍增优化

    使用\(gcd\)过程太多次会让算法变慢。
    我们通过乘法减少次数

    我们\(gcd(ac\ mod\ b,b) = gcd(a,b)\)

    我们设\(s = \prod |x0 - x_j|\ mod\ n\),我们隔\(2^k - 1\)个数,计算是否满足\(1 < gcd(s,n) < n\),取 $ k = 7$

    倍增优化
    ll Pollard_Rho(ll x) {
      ll s = 0, t = 0;
      ll c = rand() % (x - 1) + 1;
      int step = 0, goal = 1;
      ll val = 1;
      for (goal = 1;; goal <<= 1, s = t, val = 1) {
        for (step = 1; step <= goal; ++step) {
          t = f(t, c, x);
          val = val * abs(t - s) % x;
          if ((step % 127) == 0) {
            ll d = gcd(val, x);
            if (d > 1) return d;
          }
        }
        ll d = gcd(val, x);
        if (d > 1) return d;
      }
    }
    
  • 相关阅读:
    Linux 全盘备份恢复工具(Clonezilla)
    Dremel琢美电磨机配件指南
    智能设备常用电机入门指南(实物+原理图)
    硬件入门 之 20种视频接口线
    【Spring源码分析】Bean加载流程概览
    面试题:Spring为什么默认bean为单例?
    @Autowired @Resource @Qualifier的区别
    Spring的接口InitializingBean、BeanPostProcessor以及注解@PostConstruct、bean的init-method的执行先后顺序
    Spring Bean的生命周期(非常详细)
    spring中BeanFactory和FactoryBean的区别
  • 原文地址:https://www.cnblogs.com/dixiao/p/15721159.html
Copyright © 2011-2022 走看看