近似平方因子运动在评论中产生了大量的兴趣和几个优秀的解决方案。我们之前研究过Matthew Arcus使用背包算法的解决方案,该算法使用对数将问题从乘法减少到加法,从而允许像C这样的语言使用其本地数据类型来解决问题,而不是切换到大整数。
背包解决方案的工作原理如下:找到n个,系数n个并形成除数列表ds公司然后使用前面练习的子集和算法(背包的一种变体),取乘积而不是求和,找到小于平方根的除数的最大乘积n个有几种方法可以解决子集和问题。标准解决方案使用动态编程。另一个解决方案将问题空间分为两部分。这两个解都需要指数时间,尽管中间相遇解具有更好的渐近时间O(n个2n个/2). 我们还研究了解决方案这需要多项式时间来产生子集和问题的近似答案,尽管这种解决方案对我们没有帮助,因为计算所有除数已经需要指数时间。
今天,我们来看一看评论中隐藏的另一个解决方案,这是保罗·霍夫斯特拉(Paul Hofstra)提出的。以下是他的解决方案:
定义因子(facs):因子=[(1,)+元组(累加(g,mul))for,g in groupby(facs)]div=[1]对于g in因子:div=[d*f代表d in div代表f in g]返回div定义nsd5(数字):“”输出:近似平方因子方法:将因子分成两等份用小因子创建除数并排序(降序)使用大因子创建除数(<=ulimit)并进行排序大除数和小除数的循环与搜索对于最高产品<=ulimit"""ulimit=isqrt(数字)facs=rho_factors(数量)mid=长度(facs)//2降序=反转(排序(除数(facs[:mid]))升序=iter(已排序(除数(facs[mid:]))最佳=0desc=下一个(降序)为True时:对于asc升序:prod=asc*描述如果prod>最佳:如果prod<=ulimit:最佳=产品其他:打破其他:休息#while对于降序中的desc:prod=asc*描述如果prod<=ulimit:如果prod>最佳:最佳=产品打破其他:中断#while返回最佳
有了这个解决方案,我们又回到了使用大整数,并使用子集和解决方案的中间相遇变量来计算答案。该解决方案找到因子,将它们分成两半,计算每一半的除数,然后使用子集和来找到小于平方根的最大除数。注意,我们不需要计算所有的除数,只需要计算两个半的除数。
您的任务是实现Hofstra对近似平方因子问题的解决方案,并使用它计算小于190的素数乘积的近似平方因子。完成后,欢迎您阅读或运行建议的解决方案,或在下面的评论中发布自己的解决方案或讨论练习:
页:1 2