我想知道是否有一种算法可以检查给定数字是否可以计入一组素数,如果没有给出最接近的数字。 当我使用FFT时,问题总会出现。
非常感谢你的帮助。
答案 0 :(得分:2)
你的问题是关于众所周知的因子分解problem - 无法通过'快'(多项式)时间来解决。 Lenstra's elliptic algorithm是常见情况下最有效(已知)的方式,但它需要强大的数论知识 - 而且它也是次指数(但不是多项式)。
其他算法在我的帖子中通过第一个链接列在页面中,但直接尝试(暴力)这样的事情要慢得多,原因就在这里。
请注意,在“无法用多项式时间解决” - 我的意思是现在没有办法 - 但不是这样的方式不存在(至少现在,数论不能为这个问题提供这样的解决方案)
答案 1 :(得分:2)
一般来说,这看起来像一个难题,特别是找到影响你的素数组的下一个最大整数。但是,如果您的素数集不是太大,一种方法是通过获取日志将其转化为整数优化问题。以下是如何找到最小数字> n将因子分解为一组素数p_1 ... p_k
choose integers x_1,...,x_k to minimize (x_1 log p_1 + ... + x_k log p_k - log n)
Subject to:
x_1 log p_1 + ... + x_k log p_k >= log n
x_i >= 0 for all i
x_i将为您提供素数的指数。这是R中使用lpSolve的实现:
minfact<-function(x,p){
sol<-lp("min",log(p),t(log(p)),">=",log(x),all.int=T)
prod(p^sol$solution)
}
> p<-c(2,3,13,31)
> x<-124363183
> y<-minfact(x,p)
> y
[1] 124730112
> factorize(y)
Big Integer ('bigz') object of length 13:
[1] 2 2 2 2 2 2 2 2 3 13 13 31 31
> y-x
[1] 366929
>
使用大整数,即使对于大数字也是如此:
> p<-c(2,3,13,31,53,79)
> x<-as.bigz("1243631831278461278641361")
> y<-minfact(x,p)
y
>
Big Integer ('bigz') :
[1] 1243634072805560436129792
> factorize(y)
Big Integer ('bigz') object of length 45:
[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[26] 2 2 2 2 2 2 2 2 3 3 3 3 13 31 31 31 31 53 53 53
>
答案 2 :(得分:1)
这是C ++中的强力方法。它返回最近可因数的因子分解。如果N有两个等距离可分解的邻居,则返回最小的邻居。
GCC 4.7.3:g ++ -Wall -Wextra -std = c ++ 0x factorable-neighbour.cpp
#include <iostream>
#include <vector>
using ints = std::vector<int>;
ints factor(int n, const ints& primes) {
ints f(primes.size(), 0);
for (int i = 0; i < primes.size(); ++i) {
while (0< n && !(n % primes[i])) {
n /= primes[i];
++f[i]; } }
// append the "remainder"
f.push_back(n);
return f;
}
ints closest_factorable(int n, const ints& primes) {
int d = 0;
ints r;
while (true) {
r = factor(n + d, primes);
if (r[r.size() - 1] == 1) { break; }
++d;
r = factor(n - d, primes);
if (r[r.size() - 1] == 1) { break; }
}
r.pop_back();
return r; }
int main() {
for (int i = 0; i < 30; ++i) {
for (const auto& f : closest_factorable(i, {2, 3, 5, 7, 11})) {
std::cout << f << " "; }
std::cout << "\n"; }
}
答案 3 :(得分:0)
我想你有一组(小)素数S和一个整数n,你想知道的是n个因子只用S中的数字。最简单的方法似乎是:
P <- product of s in S
while P != 1 do
P <- GCD(P, n)
n <- n/P
return n == 1
使用Euclid算法计算GCD。
这个想法如下:假设S = {p1,p2,...,pk}。您可以将n唯一地写为
n = p1^n1 p2^n2 ... pk^nk * R
其中R与pi是互质的。你想知道R = 1。
然后
GCD(n, P) = prod ( pi such that ni <> 0 ).
因此,n / p将所有非零点ni减1,使它们最终变为0.最后只剩下R。
例如:S = {2,3,5},n = 5600 = 2 ^ 5 * 5 ^ 2 * 7。然后P = 2 * 3 * 5 = 30.一个得到GCD(n,p)= 10 = 2 * 5。因此n / GCD(n,p)= 560 = 2 ^ 4 * 5 * 7.
你现在回到了同样的问题:你想知道560是否可以使用S = {2,5}因此循环。所以接下来的步骤是
答案 4 :(得分:0)
int kiss_fft_next_fast_size(int n)
返回下一个最大的N,即2,3,5的总和。
另一个相关的是kf_factor function,它会对一个数n进行分解,首先拉出“漂亮的”FFT素数(例如4'在2之前被拉出)