0049算法笔记——【随机化算法】蒙特卡罗算法,主元素问题,素数测试问题

合集下载

主元素问题蒙特卡洛算法

主元素问题蒙特卡洛算法

主元素问题蒙特卡洛算法1. 引言主元素问题是一个在计算机科学领域中常见的问题,涉及到数学和算法。

在一个包含n个元素的数组中,如果某个元素的出现次数超过n/2,那么这个元素就被称为主元素。

主元素问题的解决方法有很多,其中之一就是蒙特卡洛算法。

2. 蒙特卡洛算法概述蒙特卡洛算法是一种基于概率统计的算法,通过模拟重复实验来解决问题。

它通常使用随机数来进行模拟,通过大量的模拟实验来估计问题的概率或得到问题的近似解。

在主元素问题中,蒙特卡洛算法可以用来判断一个给定的元素是否为主元素。

3. 蒙特卡洛算法解决主元素问题3.1 算法思想蒙特卡洛算法解决主元素问题的思想很简单,就是随机选择数组中的元素并判断其是否为主元素,通过多次重复实验来得到一个概率估计。

具体步骤如下:1.随机选择数组中的一个元素;2.在数组中计算该元素的出现次数;3.判断该元素的出现次数是否超过n/2;4.重复上述步骤多次,取所有实验中判断为主元素的元素中出现次数最多的作为最终的估计结果。

3.2 算法实现下面是蒙特卡洛算法解决主元素问题的实现代码(使用Python语言):import randomdef monte_carlo_majority(arr):n = len(arr)experiments = 1000experiment_results = []for _ in range(experiments):random_index = random.randint(0, n-1)random_element = arr[random_index]count = arr.count(random_element)if count > n/2:experiment_results.append(random_element)if len(experiment_results) == 0:return Nonemax_count = 0majority_element = Nonefor element in experiment_results:count = arr.count(element)if count > max_count:max_count = countmajority_element = elementreturn majority_element4. 算法分析与复杂度4.1 算法正确性分析蒙特卡洛算法解决主元素问题的正确性可以通过概率统计的方法来进行分析。

蒙特卡罗(费尔马小定理+二次探测联合算法判定1-200内的素数)算法的思想、原理和步骤

蒙特卡罗(费尔马小定理+二次探测联合算法判定1-200内的素数)算法的思想、原理和步骤

蒙特卡罗(费尔马小定理二次探测联合算法判定1-200内的素数)算法的思想、原理和步内容假如p是质数,且gcd(a,p)=1,那么a(p-1)≡1(mod p)。

证明先证两个引理:①:若a,b,c为任意3个整数,m为正整数,且(m,c)=1,则当ac≡bc(mod m)时,有a≡b(mod m)(这个很显然吧。

)②:设m是一个整数,且m>1,b是一个整数且(m,b)=1.如果a[1],a[2],a[3],a[4],…a[m]是模m的一个完全剩余系,则ba[1],ba[2],ba[3],ba[4],…ba[m]也构成模m的一个完全剩余系.证明:若存在ba[i]、ba[j]使得bai≡baj(mod m)bai≡baj(mod m),则ai≡aj(mod m)ai≡aj(mod m)。

然而根据完全剩余系的定义可知这并不存在。

然后再来证明费马小定理:构造P的完全剩余系:{1,2,3…,p−1}{1,2,3…,p−1}因为(a,p)=1(a,p)=1,根据引理②可得{a,2a,3a…,n}{a,2a,3a…,n}也是P的完全剩余系。

由完全剩余系的性质可得:(p−1)!≡(p−1)!ap−1(mod p)(p−1)!≡(p−1)!ap−1(mod p)两边同时除以(p−1)!(p−1)!,得ap−1≡1(mod p)ap−1≡1(mod p)证毕。

应用费马小定理是逆元的求解方法之一。

还可以快速计算形如ab≡c (mod p)ab≡c (mod p)这样的东西(当然p要是质数)还有就是MR素数判断MR素数判断一般的素数判断用的是筛法。

但是当素数比较大时,可能就无能为力了(判单个数最快是n−−√n)这时我们就可以考虑MR素数判断。

全名:Miller-Rabin素数测试,利用费马小定理判断一个数是否是质数。

当p为素数时,ap−1≡1(mod p)ap−1≡1(mod p),而当p不为素数时,上式有很大概率不成立。

(完整版)蒙特卡洛算法详讲

(完整版)蒙特卡洛算法详讲

Monte Carlo 法§8.1 概述Monte Carlo 法不同于前面几章所介绍的确定性数值方法,它是用来解决数学和物理问题的非确定性的(概率统计的或随机的)数值方法。

Monte Carlo 方法(MCM ),也称为统计试验方法,是理论物理学两大主要学科的合并:即随机过程的概率统计理论(用于处理布朗运动或随机游动实验)和位势理论,主要是研究均匀介质的稳定状态[1]。

它是用一系列随机数来近似解决问题的一种方法,是通过寻找一个概率统计的相似体并用实验取样过程来获得该相似体的近似解的处理数学问题的一种手段。

运用该近似方法所获得的问题的解in spirit 更接近于物理实验结果,而不是经典数值计算结果。

普遍认为我们当前所应用的MC 技术,其发展约可追溯至1944年,尽管在早些时候仍有许多未解决的实例。

MCM 的发展归功于核武器早期工作期间LosAlamos (美国国家实验室中子散射研究中心)的一批科学家。

Los Alamos 小组的基础工作刺激了一次巨大的学科文化的迸发,并鼓励了MCM 在各种问题中的应用[2]-[4]。

“Monte Carlo ”的名称取自于Monaco (摩纳哥)内以赌博娱乐而闻名的一座城市。

Monte Carlo 方法的应用有两种途径:仿真和取样。

仿真是指提供实际随机现象的数学上的模仿的方法。

一个典型的例子就是对中子进入反应堆屏障的运动进行仿真,用随机游动来模仿中子的锯齿形路径。

取样是指通过研究少量的随机的子集来演绎大量元素的特性的方法。

例如,)(x f 在b x a <<上的平均值可以通过间歇性随机选取的有限个数的点的平均值来进行估计。

这就是数值积分的Monte Carlo 方法。

MCM 已被成功地用于求解微分方程和积分方程,求解本征值,矩阵转置,以及尤其用于计算多重积分。

任何本质上属随机组员的过程或系统的仿真都需要一种产生或获得随机数的方法。

这种仿真的例子在中子随机碰撞,数值统计,队列模型,战略游戏,以及其它竞赛活动中都会出现。

主元素问题蒙特卡洛算法

主元素问题蒙特卡洛算法

主元素问题蒙特卡洛算法主元素问题主元素问题是指在一个序列中,出现次数超过一半的元素被称为主元素。

该问题可以通过多种算法进行解决,如暴力枚举、哈希表、排序和分治等。

其中,蒙特卡洛算法是一种随机化算法,可以用于求解主元素问题。

蒙特卡洛算法蒙特卡洛算法是一种基于随机采样的方法,常用于求解复杂问题。

该算法通过随机采样来估计某个数学量的值,并且可以控制误差范围。

在主元素问题中,我们可以使用蒙特卡洛算法来估计序列中出现次数超过一半的元素是否存在。

具体实现1. 随机选择一个数作为候选主元素。

2. 遍历整个序列,统计候选主元素出现的次数。

3. 如果候选主元素出现次数超过了序列长度的一半,则认为该候选主元素是真正的主元素。

4. 如果候选主元素出现次数没有超过序列长度的一半,则重新选择一个数作为候选主元素并重复步骤2和3。

分析蒙特卡洛算法虽然不能保证总能找到主元素,但是可以保证找到的主元素是正确的概率非常高。

具体来说,假设候选主元素在序列中出现的次数为k,则根据概率学知识可知,随机选择一个数后,该数成为候选主元素并且在序列中出现了k次的概率为C(n,k)/2^n,其中n为序列长度。

当k>n/2时,该概率大于1/2,因此可以认为候选主元素是真正的主元素。

而当k<=n/2时,需要多次随机选择才能找到真正的主元素。

代码实现下面给出蒙特卡洛算法的Python代码实现:```pythonimport randomdef majority_element(nums):candidate = Nonecount = 0for num in nums:if count == 0:candidate = numif num == candidate:count += 1else:count -= 1return candidatedef monte_carlo_majority_element(nums):while True:candidate = random.choice(nums)if nums.count(candidate) > len(nums) // 2:return candidatenums = [1, 2, 3, 4, 5, 5, 5]print(majority_element(nums)) # 输出:5print(monte_carlo_majority_element(nums)) # 输出:5```上述代码中,majority_element函数使用了Boyer-Moore投票算法求解主元素问题,monte_carlo_majority_element函数使用了蒙特卡洛算法求解主元素问题。

数学建模算法之蒙特卡罗方法——原理编程及应用

数学建模算法之蒙特卡罗方法——原理编程及应用

数学建模算法之蒙特卡罗方法——原理编程及应用蒙特卡罗方法是一种基于随机数的数学建模算法,它在估计和模拟复杂的数学问题时非常有用。

蒙特卡罗方法的原理是通过随机抽样来进行近似计算,然后使用统计学方法来分析和推断结果。

蒙特卡罗方法的核心思想是通过进行大量的随机样本实验,来估计问题的解或者概率。

它的基本过程如下:1.问题建模:将要解决的问题转化为数学模型,并明确需要估计的量。

2.随机抽样:根据问题的性质和要求,设计合适的随机抽样方法,生成大量的随机样本。

3.计算估计量:对每个样本,将其代入数学模型,计算得到估计量的值。

4.统计分析:对所有样本的估计量进行统计分析,包括计算均值、方差等。

5.结果解释:根据统计分析的结果,得出对问题的估计值和置信区间。

蒙特卡罗方法的一个重要特点是可以处理复杂的问题,因为需要进行大量的随机实验。

它广泛应用于科学研究、金融决策、工程设计等领域。

下面以两个实际应用为例介绍蒙特卡罗方法的具体编程和应用。

实例一:估计π的值蒙特卡罗方法可以用来估计π的值。

其基本思路是以原点为中心,边长为2的正方形内切一个以原点为圆心的半径为1的圆,通过生成大量的随机点,并统计落在圆内的点的个数来估计圆的面积,然后根据面积比例来估计π。

编程步骤如下:1.生成随机点:生成大量的随机点,均匀分布在正方形内。

2.判断点位置:判断每个点是否落在圆内,即判断点的横坐标和纵坐标的平方和是否小于13.统计结果:统计圆内的点的个数。

4.计算面积和π的估计值:根据圆内点的个数,计算圆的面积和π的估计值。

实例二:金融风险分析蒙特卡罗方法可以用于金融风险分析,例如估计一些投资组合的回报率和风险。

编程步骤如下:1.生成随机数:生成符合历史回报率的随机数序列,代表不同的投资回报率。

2.计算投资回报率:根据生成的随机数序列,计算投资组合的回报率。

3.重复实验:重复上述步骤多次,生成多个投资回报率的样本。

4.统计分析:对多个投资回报率样本进行统计分析,计算均值、方差等指标。

蒙特卡洛算法的计算原理

蒙特卡洛算法的计算原理

蒙特卡洛算法的计算原理今天来聊聊蒙特卡洛算法的计算原理。

我最初接触到蒙特卡洛算法的时候,就像是进入了一个充满概率魔法的世界。

你想想看啊,生活中有这么个场景,假如你想知道一个不规则形状池塘的面积。

你可能会觉得很头疼,因为它不是规规矩矩的正方形或者圆形,很难直接计算。

这时候蒙特卡洛算法的思想就有点像咱们来个随机大作战。

咱们可以先找个已知面积的大长方形框住这个池塘,比如这个长方形就是100平方米。

然后呢,就开始让一群小伙伴随便往这个长方形区域里扔石头(这就相当于随机生成点)。

大家扔了很多很多石头之后,我们就数一数落在池塘里的石头数量和总共扔出的石头数量。

假设总共扔了1000块石头,落在池塘里的有600块,那按照比例,这个池塘的面积就大概是60平方米啦。

这种看似简单粗糙的随机模拟的方法,背后就是蒙特卡洛算法的基本思想。

说到这里,你可能会问:“这在数学和计算机里有什么理论依据呢?”其实它是基于概率论中的大数定律。

大数定律简单来说,就是当随机试验的次数足够多的时候,某些事件发生的频率就会非常接近它的概率。

蒙特卡洛算法就是不断地进行随机试验,让结果越来越接近那个准确的解。

打个比方吧,蒙特卡洛算法就像在一个装满彩球的大箱子里猜特定颜色球的数量。

每次随机拿出一个球,记录颜色后再放回去。

刚开始的时候,预测结果可能偏差很大,但拿的次数越多,就越接近真实的颜色比例,进而能算出那种颜色球的大致数量。

蒙特卡洛算法在很多实际应用中都超级有用。

比如说金融领域里风险评估。

股票的价格波动受到众多复杂因素的影响,就像一个超级复杂的不规则图形。

这时候用蒙特卡洛算法,把影响股票价格的各类因素当成那些随机扔的点,通过大量的模拟(多组随机数据运行股票价格模型),就能得到股票价格在一定情况下波动范围的大概情形,从而评估风险。

在物理学里模拟粒子运动也是如此。

在一个有着复杂磁场、电场的空间里,粒子的运动轨迹很难通过确定的方程式算出来。

蒙特卡洛算法就可以随机模拟粒子在这个空间里的运动,不停地试验不同的起始状态、不同的运动方向等,通过大量的模拟就能得到粒子可能的分布、运动范围等信息。

蒙特卡罗算法介绍

蒙特卡罗算法介绍

蒙特卡罗算法介绍
蒙特卡罗是⼀类随机⽅法的统称。

这类⽅法的特点是,可以在随机采样上计算得到近似结果,随着采样的增多,得到的结果是正确结果的概率逐渐加⼤,但在(放弃随机采样,⽽采⽤类似全采样这样的确定性⽅法)获得真正的结果之前,⽆法知道⽬前得到的结果是不是真正的结果。

举例说明,⼀个有10000个整数的集合,要求其中位数,可以从中抽取m<10000个数,把它们的中位数近似地看作这个集合的中位数。

随着m增⼤,近似结果是最终结果的概率也在增⼤,但除⾮把整个集合全部遍历⼀边,⽆法知道近似结果是不是真实结果。

另外⼀个例⼦,给定数N,要求它是不是素数,可以任选m个⼩于N的数,看其中有没有能整除N的数,如果没有则判断为素数。

这和通常见到的蒙特卡罗例⼦不同,近似结果往往错得更离谱,但随着m增⼤,近似结果是最终结果的概率也在增⼤。

把蒙特卡罗⽅法和另外⼀类⽅法——拉斯维加斯⽅法[1]——对⽐⼀下,更容易了解哪些⽅法属于蒙特卡罗,哪些不属于。

拉斯维加斯⽅法是另⼀类随机⽅法的统称。

这类⽅法的特点是,随着采样次数的增多,得到的正确结果的概率逐渐加⼤,如果随机采样过程中已经找到了正确结果,该⽅法可以判别并报告,但在但在放弃随机采样,⽽采⽤类似全采样这样的确定性⽅法之前,不保证能找到任何结果(包括近似结果)。

举例说明,有⼀个有死胡同但⽆环路的迷宫,要求从⼊⼝⾛到出⼝的⼀条路径。

可以从⼊⼝出发,在每个叉路⼝随机选择⼀个⽅向前⾏,到死胡同则报告失败并回到⼊⼝重新试探,到出⼝则报告成功。

随着试探次数增多,找到⼀条⼊⼝到出⼝的路径的概率增⼤,但除⾮全枚举,即使试10000年,也⽆法保证找到任何要求的路径。

蒙特卡罗方法讲解

蒙特卡罗方法讲解

蒙特卡罗方法讲解
蒙特卡洛方法(Monte Carlo Method)又称几何表面积法,是用来解决统计及数值分析问题的一种算法。

蒙特卡洛方法利用了随机数,其特点是算法简单,可以解决复杂的统计问题,并得到较好的结果。

蒙特卡洛方法可以被认为是统计学中一种具体的模拟技术,可以通过模拟仿真的方式来估算一个问题的可能解。

它首先利用穷举或随机的方法获得随机变量的统计数据,然后针对该统计数据利用数理统计学的方法获得解决问题的推断性结果,例如积分、概率等。

蒙特卡洛方法在计算机科学中的应用非常广泛,可以用来模拟统计物理、金融工程、统计数据反演、运行时参数优化以及系统可靠性计算等问题,因此广泛被用于许多不同的领域。

蒙特卡洛方法的基本思想是:将一个难以解决的复杂问题,通过把它分解成多个简单的子问题,再用数学方法求解这些子问题,最后综合这些简单问题的结果得到整个问题的解。

蒙特卡洛方法的这种思路,也称作“积分”,即将一个复杂的问题,分解成若干小问题,求解它们的结果,再综合起来,得到整体的结果。

蒙特卡洛方法以蒙特卡罗游戏为基础,用统计学的方法对游戏进行建模。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、蒙特卡罗算法基本概述蒙特卡罗(Monte Carlo)方法,又称随机抽样或统计试验方法。

传统的经验方法由于不能逼近真实的物理过程,很难得到满意的结果,而蒙特卡罗方法由于能够真实地模拟实际物理过程,故解决问题与实际非常符合,可以得到很圆满的结果。

在实际应用中常会遇到一些问题,不论采用确定性算法或随机化算法都无法保证每次都能得到正确的解答。

蒙特卡罗算法则在一般情况下可以保证对问题的所有实例都以高概率给出正确解,但是通常无法判定一个具体解是否正确。

设p是一个实数,且1/2<p<1。

如果一个蒙特卡罗算法对于问题的任一实例得到正确解的概率不小于p,则称该蒙特卡罗算法是p正确的,且称p-1/2是该算法的优势。

如果对于同一实例,蒙特卡罗算法不会给出2个不同的正确解答,则称该蒙特卡罗算法是一致的。

有些蒙特卡罗算法除了具有描述问题实例的输入参数外,还具有描述错误解可接受概率的参数。

这类算法的计算时间复杂性通常由问题的实例规模以及错误解可接受概率的函数来描述。

原理思想当所要求解的问题是某种事件出现的概率,或者是某个随机变量的期望值时,它们可以通过某种“试验”的方法,得到这种事件出现的频率,或者这个随机变数的平均值,并用它们作为问题的解。

这就是蒙特卡罗方法的基本思想。

蒙特卡罗方法通过抓住事物运动的几何数量和几何特征,利用数学方法来加以模拟,即进行一种数字模拟实验。

它是以一个概率模型为基础,按照这个模型所描绘的过程,通过模拟实验的结果,作为问题的近似解。

主要步骤蒙特卡罗解题归结为三个主要步骤:构造或描述概率过程;实现从已知概率分布抽样;建立各种估计量。

1)构造或描述概率过程:对于本身就具有随机性质的问题,如粒子输运问题,主要是正确描述和模拟这个概率过程,对于本来不是随机性质的确定性问题,比如计算定积分,就必须事先构造一个人为的概率过程,它的某些参量正好是所要求问题的解。

即要将不具有随机性质的问题转化为随机性质的问题。

2)实现从已知概率分布抽样:构造了概率模型以后,由于各种概率模型都可以看作是由各种各样的概率分布构成的,因此产生已知概率分布的随机变量(或随机向量),就成为实现蒙特卡罗方法模拟实验的基本手段,这也是蒙特卡罗方法被称为随机抽样的原因。

最简单、最基本、最重要的一个概率分布是(0,1)上的均匀分布(或称矩形分布)。

随机数就是具有这种均匀分布的随机变量。

随机数序列就是具有这种分布的总体的一个简单子样,也就是一个具有这种分布的相互独立的随机变数序列。

产生随机数的问题,就是从这个分布的抽样问题。

在计算机上,可以用物理方法产生随机数,但价格昂贵,不能重复,使用不便。

另一种方法是用数学递推公式产生。

这样产生的序列,与真正的随机数序列不同,所以称为伪随机数,或伪随机数序列。

不过,经过多种统计检验表明,它与真正的随机数,或随机数序列具有相近的性质,因此可把它作为真正的随机数来使用。

由已知分布随机抽样有各种方法,与从(0,1)上均匀分布抽样不同,这些方法都是借助于随机序列来实现的,也就是说,都是以产生随机数为前提的。

由此可见,随机数是我们实现蒙特卡罗模拟的基本工具。

建立各种估计量:一般说来,构造了概率模型并能从中抽样后,即实现模拟实验后,我们就要确定一个随机变量,作为所要求的问题的解,我们称它为无偏估计。

3)建立各种估计量:相当于对模拟实验的结果进行考察和登记,从中得到问题的解。

例如:检验产品的正品率问题,我们可以用1表示正品,0表示次品,于是对每个产品检验可以定义如下的随机变数Ti,作为正品率的估计量:于是,在N次实验后,正品个数为:显然,正品率p 为:不难看出,Ti为无偏估计。

当然,还可以引入其它类型的估计,如最大似然估计,渐进有偏估计等。

但是,在蒙特卡罗计算中,使用最多的是无偏估计。

用比较抽象的概率语言描述蒙特卡罗方法解题的手续如下:构造一个概率空间(W ,A,P),其中,W 是一个事件集合,A是集合W 的子集的s 体,P是在A上建立的某个概率测度;在这个概率空间中,选取一个随机变量q (w ),w Î W ,使得这个随机变量的期望值正好是所要求的解Q ,然后用q (w )的简单子样的算术平均值作为Q 的近似值。

2、主元素问题问题描述设T[1:n]是一个含有n个元素的数组。

当|{i|T[i]=x}|>n/2时,称元素x是数组T的主元素。

例如:数组T[]={5,5,5,5,5,5,1,3,4,6}中,元素T[0:5]为数组T[]的主元素。

问题求解算法随机选择数组元素x,由于数组T的非主元素个数小于n/2,所以,x不为主元素的概率小于1/2。

因此判定数组T的主元素存在性的算法是一个偏真1/2正确的算法。

50%的错误概率是不可容忍的,利用重复调用技术将错误概率降低到任何可接受的范围内。

对于任何给定的>0,算法majorityMC重复调用次算法majority。

它是一个偏真蒙特卡罗算法,且其错误概率小于。

算法majorityMC所需的计算时间显然是。

算法具体代码如下:[cpp]view plain copy1.//随机化算法蒙特卡罗算法主元素问题2.#include "stdafx.h"3.#include "RandomNumber.h"4.#include <cmath>5.#include <iostream>ing namespace std;7.8.//判定主元素的蒙特卡罗算法9.template<class Type>10.bool Majority(Type *T,int n)11.{12. RandomNumber rnd;13.int i = rnd.Random(n);14.15. Type x = T[i]; //随机选择数组元素16.int k = 0;17.18.for(int j=0; j<n; j++)19. {20.if(T[j] == x)21. {22. k++;23. }24. }25.26.return (k>n/2); //k>n/2时,T含有主元素27.}28.29.//重复k次调用算法Majority30.template<class Type>31.bool MajorityMC(Type *T,int n,double e)32.{33.int k = ceil(log(1/e)/log((float)2));34.for(int i=1; i<=k; i++)35. {36.if(Majority(T,n))37. {38.return true;39. }40. }41.return false;42.}43.44.int main()45.{46.int n = 10;47.float e = 0.001;48.int a[] = {5,5,5,5,5,5,1,3,4,6};49. cout<<"数组a的元素如下:"<<endl;50.for(int i=0; i<10; i++)51. {52. cout<<a[i]<<" ";53. }54. cout<<endl;55. cout<<"调用MajorityMC判断数组是否含有主元素结果是:"<<MajorityMC(a,n,e)<<endl;56.}程序运行结果如图:3、素数测试问题数学原理Wilson定理:对于给定的正整数n,判定n是一个素数的充要条件是(n-1)! -1(mod n)。

费尔马小定理:如果p是一个素数,且0<a<p,则a^(p-1)(mod p)。

二次探测定理:如果p是一个素数,且0<x<p,则方程x^21(mod p)的解为x=1,p-1。

Carmichael数:费尔马小定理是素数判定的一个必要条件。

满足费尔马小定理条件的整数n未必全是素数。

有些合数也满足费尔马小定理的条件,这些合数称为Carmichael数。

前3个Carmichael数是561,1105,1729。

Carmichael数是非常少的,在1~100000000的整数中,只有255个Carmichael数。

求a^m(mod n)的算法设m的二进制表示为b k b k-1…b1b0(b k=1)。

例:m=41=101001(2),b k b k-1…b1b0=101001,(k=5)。

可以这样来求a^m:初始C←1。

b5=1:C←C^2(=1),∵b k=1,做C←a*C(=a);b5b4=10:C←C^2(=a^2),∵b k-1=0,不做动作;b5b4b3=101:C←C^2(=a^4),∵b k-2=1,做C←a*C(=a^5);b5b4b3b2=1010:C←C^2(=a^10),∵b k-3= b2=0,不做动作;b5b4b3b2b1=10100:C←C^2(=a^20),∵b k-4= b1=0,不做动作;b5b4b3b2b1b0=101001:C←C^2(=a^40),∵b k-5= b0=1,做C←a*C(=a^41)。

最终要对am求模,而求模可以引入到计算中的每一步:即在求得C2及a*C之后紧接着就对这两个值求模,然后再存入C。

这样做的好处是存储在C中的最大值不超过n-1,于是计算的最大值不超过max{(n-1)^2,a(n-1)}。

因此,即便am很大,求am(mod n)时也不会占用很多空间。

程序具体代码如下:[cpp]view plain copy1.//随机化算法蒙特卡罗算法素数测试问题2.#include "stdafx.h"3.#include "RandomNumber.h"4.#include <cmath>5.#include <iostream>ing namespace std;8.//计算a^p mod n,并实施对n的二次探测9.void power(unsigned int a,unsigned int p,unsigned int n,unsigned int &result,bool &composite)10.{11. unsigned int x;12.if(p == 0)13. {14. result = 1;15. }16.else17. {18. power(a,p/2,n,x,composite); //递归计算19. result = (x*x)%n; //二次探测20.21.if((result == 1) && (x!=1) && (x!=n-1))22. {23. composite = true;24. }25.26.if((p%2)==1)27. {28. result = (result*a)%n;29. }30. }31.}32.33.//重复调用k次Prime算法的蒙特卡罗算法34.bool PrimeMC(unsigned int n,unsigned int k)35.{36. RandomNumber rnd;37. unsigned int a,result;38.bool composite = false;39.40.for(int i=1; i<=k; i++)41. {42. a = rnd.Random(n-3)+2;43. power(a,n-1,n,result,composite);44.if(composite || (result!=1))45. {46.return false;47. }48. }49.return true;51.52.int main()53.{54.int k = 10;55.for(int i=1010;i<1025;i++)56. {57. cout<<i<<"的素数测试结果为:"<<PrimeMC(i,k)<<endl;58. }59.return 0;60.}程序运行结果如图:。

相关文档
最新文档