• 拉斯维加斯随机化算法求解整数因子分解


    问题描述

         设n>1是一个整数。关于整数n的因子分解问题是找出n的如下形式的唯一分解式。其中,p1<p2<…<pk是k个素数,m1,m2,…,mk是k个正整数。如果n是一个合数,则n必有一个非平凡因子x,1<x<n,使得x可以整除n。给定一个合数n,求n的一个非平凡因子的问题称为整数n的因子分割问题。

    下面算法split(n)可以对整数因子分割:

    int Split(int n)
    {
        int m = floor(sqrt(double(n)));
        for (int i=2; i<=m; i++)
        {
            if (n%i==0)
            {
                return i;
            }
        }
        return 1;
    }
    View Code

    算法split(n)是对范围在1~x的所有整数进行了试除而得到范围在1~x^2的任一整数的因子分割。 

     Pollard p - 1 方法由Pollard 于1974 年提出,用来找到给定合数n的一个因子d。Pollard算法用于Split(n)相同工作量就可以得到在1~x^4范围内整数的因子分割。具体过程如下:在开始时选取0~n-1范围内的随机数,然后递归地由
    产生无穷序列对于i=2^k,k=0,1,.....以及2^k<j<=2^(k+1),算法计算出xj-xi与n的最大公因子d=gcd(xj-xi,n)。如果d是n的非平凡因子,则实现对n的一次分割,算法输出n的因子d。

         算法具体实现如下:其中gcd(a,b)是求两个整数最大公因素的欧几里得算法。

    //随机化算法 拉斯维加斯算法 因子分割问题
    #include "stdafx.h"
    #include "RandomNumber.h"
    #include <iostream>
    using namespace std;
     
    //求整数a和b最大公因数的欧几里得算法
    int gcd(int a,int b)
    {
        if(b==0)
        {
            return a;
        }
        else
        {
            return gcd(b,a%b);
        }
    }
     
    //求整数n因子分割的拉斯维加斯算法
    void Pollard(int n)
    {
        RandomNumber rnd;
        int i = 1;
        int x = rnd.Random(n);            //随机整数
        int y = x;
        int k = 2;
     
        while(true)
        {
            i++;
            x = (x*x - 1) % n;            //x[i]=(x[i-1]^2-1) mod n
            int d = gcd(y-x,n);            //求n的非平凡因子
     
            if((d>1) && (d<n))
            {
                cout<<d<<endl;//因子分割问题:求n的[一]个非平凡因子的问题
                return;
            }
     
            if(i == k)
            {
                y = x;
                k *= 2;
            }
        }
    }
     
    int main()
    {
        int n = 1024;
        cout<<n<<"的非平凡因子:"<<endl;
        Pollard(n);
        return 0;
    }
    View Code
    #include"time.h"
    //随机数类
    const unsigned long maxshort = 65536L;
    const unsigned long multiplier = 1194211693L;
    const unsigned long adder = 12345L;
     
    class RandomNumber
    {
        private:
            //当前种子
            unsigned long randSeed;
        public:
            RandomNumber(unsigned long s = 0);//构造函数,默认值0表示由系统自动产生种子
            unsigned short Random(unsigned long n);//产生0:n-1之间的随机整数
            double fRandom(void);//产生[0,1)之间的随机实数
    };
     
    RandomNumber::RandomNumber(unsigned long s)//产生种子
    {
        if(s == 0)
        {
            randSeed = time(0);//用系统时间产生种子
        }
        else
        {
            randSeed = s;//由用户提供种子
        }
    }
     
    unsigned short RandomNumber::Random(unsigned long n)//产生0:n-1之间的随机整数
    {
        randSeed = multiplier * randSeed + adder;//线性同余式
        return (unsigned short)((randSeed>>16)%n);
    }
     
    double RandomNumber::fRandom(void)//产生[0,1)之间的随机实数
    {
        return Random(maxshort)/double(maxshort);
    }
    View Code

    运行结果:

     对Pollard算法更深入的分析可知,执行算法的while循环约次后,Pollard算法会输出n的一个因子p。由于n的最小素因子,故Pollard算法可在O(n^(1/4))时间内找到n的一个素因子。在上述Polllard算法中还可将产生序列Xi的递归式改作

    Xi=(Xi-1^2-c)mod n,其中,c是一个不等于0和2的整数。

    参考文献:王晓东《算法设计与分析》第二版

                      https://blog.csdn.net/liufeng_king/article/details/9246821

  • 相关阅读:
    Metasploit学习笔记——强大的Meterpreter
    Metasploit学习笔记——社会工程学
    Mono for Andriod学习与实践(1)— 初体验
    Xamarin.Android 在VS下调试时提示 In mgmain JNI_OnLoad 程序“Mono”已退出 解决办法
    Xamarin.Android 使用 SQLiteOpenHelper 进行数据库操作
    WCF 部署时,soap:address location 显示的是电脑名,而不是ip地址
    英特尔® 硬件加速执行管理器安装指南 — Microsoft Windows*
    使用Intel HAXM 加速你的Android模拟器
    Xamarin Studio Android 配置
    Xamarin C# Android for Visual Studio 平台安装
  • 原文地址:https://www.cnblogs.com/cy0628/p/14010274.html
Copyright © 2020-2023  润新知