改进Lemoine猜想的代码

时间:2015-07-23 12:00:23

标签: performance matlab vectorization

我正在尝试改进以下代码:

编写代码是为了解决以下等式:

2*n + 1 = p + 2*q

此等式表示给定整数n,值2*n + 1始终可以用p + 2*q表示,其中pq是素数。 这已在多年前得到证明,称为Lemoine's conjecture

代码的输入是一个数字(n>2),输出将是一个包含2列有效素数的矩阵。

n = 23;
S =  2*n+1;
P = primes(S);
V = [];
kk = 1;
for ii=1:length(P)
    for jj=1:length(P)
            if (S == P(ii)+2*P(jj))
                V(kk,:) = [P(ii) P(jj)];
                kk = kk + 1;
            end
    end
end

结果将是;

V =

    13    17
    37     5
    41     3
    43     2

,例如:

2*23+1 = 43 + 2*2

有没有办法摆脱MATLAB中的for循环?

更新

@Daniel建议,也有效

n = 23;
S =  2*n+1;
P = primes(S);
for ii=1:length(P)
    if ismember(S - P(ii),P)
        V(kk,:) = [P(ii) S-P(ii)];
    end
end

2 个答案:

答案 0 :(得分:2)

您可以使用bsxfun -

将这些循环替换为矢量化解决方案
[R,C] = find(bsxfun(@eq,P-S,-2*P(:)));
V = [P(C) ; P(R)].'

使用n = 100000,我得到的运行时间是 -

------------ With loopy solution
Elapsed time is 33.789586 seconds.
----------- With bsxfun solution
Elapsed time is 1.338330 seconds.

答案 1 :(得分:1)

这是另一种实现方式:

p_candidates=primes(2*n+1-4);
q_candidates=p_candidates(p_candidates<n+1);
p_needed=2*n+1-2*q_candidates;
solution=ismember(p_needed,p_candidates);
m=[q_candidates(solution);p_needed(solution)];
  1. 计算p和q的上限,从小于这些边界的素数开始。
  2. 选择q,计算p(p_needed)的对应值。
  3. 检查所需的值是否为素数
相关问题