Algorithm 求整数幂根

Algorithm 求整数幂根,algorithm,exponentiation,Algorithm,Exponentiation,求一个数的所有整数幂根的最佳(最有效)算法是什么 也就是说,给定一个数字n,我想找到b(基数)和e(指数),以便 n=be 我想获得b和e 注:nb和e是正整数这取决于任务的维度,我的方法是否能满足您的需要 首先,有一个显而易见的解决方案:e=1,对吗? 从那时起,如果你想找到所有的解:我能想到的所有算法都需要找到n的素因子。如果这仅仅是一个独立的任务,没有什么比对质数施加暴力更好的了(如果我没有错的话)。在找到第一个素因子p及其对应的指数(即最大数k,即p^k/n)后,只需检查k的除数是否为e

求一个数的所有整数幂根的最佳(最有效)算法是什么

也就是说,给定一个数字
n
,我想找到
b
(基数)和
e
(指数),以便

n=be

我想获得
b
e


注:
n
b
e
正整数

这取决于任务的维度,我的方法是否能满足您的需要

首先,有一个显而易见的解决方案:e=1,对吗?
从那时起,如果你想找到所有的解:我能想到的所有算法都需要找到n的素因子。如果这仅仅是一个独立的任务,没有什么比对质数施加暴力更好的了(如果我没有错的话)。在找到第一个素因子p及其对应的指数(即最大数k,即p^k/n)后,只需检查k的除数是否为e。对于每一个这样的指数l(同样,l迭代k的所有除数),您可以使用二进制搜索来查看n的第l个根是否为整数(相当于找到新的解)。

首先查找
n的素因式分解:
n=p1e1 p2e2 p3e3…

然后找到
e1
e2
e3
。。。通过使用

现在,对于
g
的任何系数
e
,您可以使用:

b=p1e1/e p2e2/e p3e3/e…


你有
n=be

我认为蛮力方法应该有效:从2开始尝试所有
e
s(1是一个微不足道的解决方案),然后再从2开始尝试
r=n^1/e
,一个
。如果
r
小于2,则停止。否则,计算
ceil(r)^e
floor(r)^e
,并将它们与
n
进行比较(您需要
ceil
floor
来补偿浮点表示中的错误)。假设整数适合64位,则不需要尝试超过64个
e

下面是C++中的一个示例:

#include <iostream>
#include <string>
#include <sstream>
#include <math.h>
typedef long long i64;
using namespace std;
int main(int argc, const char* argv[]) {
    if (argc == 0) return 0;
    stringstream ss(argv[1]);
    i64 n;
    ss >> n;
    cout << n << ", " << 1 << endl;
    for (int e = 2 ; ; e++) {
        double r = pow(n, 1.0 / e);
        if (r < 1.9) break;
        i64 c = ceil(r);
        i64 f = floor(r);
        i64 p1 = 1, p2 = 1;
        for (int i = 0 ; i != e ; i++, p1 *= c, p2 *= f);
        if (p1 == n) {
            cout << c << ", " << e << endl;
        } else if (p2 == n) {
            cout << f << ", " << e << endl;
        }
    }
    return 0;
}

混合interjay和dasblinkenlight的方法。首先在
n
的素因子分解中找到所有小素因子(如果有)及其指数。“small”的适当值取决于
n
,对于中等大小的
n
p
e
必须是整数吗?很抱歉,我忘了提及,我已经更新了问题,我仍在搜索以查找内容。如果你的问题是素数分解,首先找到所有小于
n/2
的素数,并创建一个大小为n/2+1的int数组,在启动时将其命名为零,然后对每个素数(p)测试
n/p==0
,直到n/p==0,设置n/=p并增加A[p],然后你将有素数分解,如果你想用更快的方法,请在新问题中提问。@SaeedAmiri没有必要去
n/2
,只要去
sqrt(n)
。任何剩余的因子都会自动成为最后一个素数。实际上我正在尝试实现一个素数分解算法,我需要解决这个问题。具有讽刺意味的是,你要我找出主要因素。@ChingPing:这远远不是一个好方法。求整数幂根是一个非常简单的多项式时间问题,而整数因式分解是一个非常复杂的问题,没有已知的多项式时间算法。@SergeDundich如果n非常大,它是多项式吗?否则我不认为你的观点,因为为小数字寻找素数也是多项式!更妙的是,我们有像rho pollard这样的大数字算法!另外请注意问题是“寻找所有整数幂根”@ChingPing:“如果n非常大,它是多项式吗?”当然是。谈到多项式(输入大小为
P(s)=P(log2(n))
)运行时间是指运行时间
t(s)=O(P(s))
对于任何可能的
n
,因此对于任何可能的
s=log2(n)
,包括非常大的问题。@ChingPing:对于已知的问题,没有多项式时间算法。所有已知的算法,包括Pollard rho、二次筛、通用数字域筛(最著名的通用算法)都比多项式算法慢得多。看起来似乎有道理,你能用一些代码来澄清这个解决方案吗?@dasblinkenlight:这是一个完美解决方案的正确想法。您只需尝试从
2
log2(n)
(对数基数2)的
e
。唯一的问题是求幂代码
for(inti=0;i!=e;i++,p1*=c,p2*=f)
远远不是最优的(您可以执行小于
2*log2(e)
的乘法,而不是
e
乘法)。但是主要的概念无论如何都是正确的。@SergeDundich我保留了原始的
幂(c,e)
code,因为
e
的硬下限是64。
power(c,e)
的智能算法会产生更多的问题(即使我现在的
for
循环也可能从注释中受益;
log2
power算法会更不明显),所以我保留了这个微不足道的算法。”(如果我没有错的话)“你错了。该算法比“对素数施加暴力”要快得多。找到原始问题所要求的所有整数幂根是一个简单得多的(多项式时间)问题。正如一些人可能会说的:“唯一比正确更好的事情就是错误。”谢谢你们教育我。PS:在我发布后不久,我意识到我提出的解决方案介于两者之间,我几乎想不出我的解决方案是最优的(可能是分解巨大的数字,你知道其中有非常小的素因子?)。
65536, 1
256, 2
16, 4
4, 8
2, 16