计算小数周期的Julia码优化

计算小数周期的Julia码优化,julia,Julia,我在试着解决ProjetEuler的问题417。我写了一段代码来优化和计算这个过程,但这还远远不够。 我的算法是基于这个网站上的发现 代码中唯一的任务部分是check函数,但不管我怎么看,它的时间复杂度都不足以让我的电脑处理。但它的速度却慢得令人痛苦。 我添加了更多的进程来提供帮助,它似乎将运行时的速度提高了一倍以上,但这还不够 using Distributed; @everywhere using SharedArrays addprocs() function createDict(lim

我在试着解决ProjetEuler的问题417。我写了一段代码来优化和计算这个过程,但这还远远不够。 我的算法是基于这个网站上的发现

代码中唯一的任务部分是check函数,但不管我怎么看,它的时间复杂度都不足以让我的电脑处理。但它的速度却慢得令人痛苦。 我添加了更多的进程来提供帮助,它似乎将运行时的速度提高了一倍以上,但这还不够

using Distributed;
@everywhere using SharedArrays
addprocs()
function createDict(limit)
   a = Dict(2 => true);
   for i = 0:(floor(log2(limit))+1)
       for j = 0:13
           if ((2^i * 5^j) <= limit)
               get!(a,(2^i * 5^j),true)
           end
       end
   end
   return a;
end
arr = createDict(10^6)

@everywhere function check(x)
   mem = []
   for i = 1:x
       power = i-1;
       num = (BigInt(10)^power) % x
       push!(mem,num)
       for j = 1:(length(mem)-1)
           (mem[j] == num ) && return (i-j);
       end    
   end
end

@everywhere function test(limit,arr)
    a = SharedArray{Int16}(limit)
    @sync @distributed for i=3:limit
        flag = false;
        flag = get(arr,i,false)
        (flag == false) && (a[i] = check(i))
    end
    return sum(a);
end
@elapsed test(10^6,arr)
使用分布式;
@到处都在使用共享光线
addprocs()
函数createDict(限制)
a=Dict(2=>true);
对于i=0:(楼层(对数2(极限))+1)
对于j=0:13

如果((2^i*5^j)记住我认为解决此问题的关键在别处(遵循SO政策,我不想对此发表评论),则重写
检查
以提高其速度的方法如下:

function check(x)
    mem = Dict{Int,Int}()
    num = 1
    for i = 1:x
        haskey(mem, num) && return i - mem[num]
        mem[num] = i
        num = 10num % x
    end
end

你能澄清一下你的问题到底是什么吗?如果是为了使你的算法在实现上更有效,那么答案是,无论你使用什么实现或什么编程语言,使用这种算法都无法有效地解决这个问题。例如,请注意,即使是计算
BigInt(10)^功率
其中功率的大小为
100\u 000\u 000
需要1秒的时间,您需要进行数百万次计算。即使在
极限=10^4
时,运行时间约为194[秒]在我的机器中,我认为我的编码方式有问题。谢谢你的回答,我将研究其他关于处理高功率的算法,因为据我所知,它在这里很重要,因为数字算法可能更精确,但当它们接近结果时,它们总是有汇总错误。尽管有一个问题我想得到答案的离子,为什么
1//5==1/5
给出的是假的而
1//2==1/2
是真的?两者都是真的。我将循环中的
BigInt(10)^power
更改为
pow*=10
,这样
num=po%x
在1初始化时,速度很小,得到
174[秒]
而不是
194[秒]
使用
limit=10^4
。虽然我似乎不知道什么是完全可以理解的,但我甚至不想听到答案,如果它的算法不同,那么至少在我解决它之前不会。哈哈。无论如何,再次感谢你的帮助。我想问你是否介意为什么会有这样的问题与检查函数的性能差异大?复杂度方面的挖掘不<代码>n(n-1)
循环和您的
n
虽然我的代码中的内部循环只是布尔检查。我在这两个循环上都使用了
@time
,发现我的循环分配了更多的内存,即使数组/dict大小相同,甚至更多,所以我再次尝试将数组配置为
mem={Int,1}()
而分配刚刚增加,我将参考您在问题中发布的关于差异的代码。导致差异的原因有以下几点:1)
mem=[]
创建一个类型不稳定的
Any
数组;它不仅占用更多内存,而且速度也较慢。2) 通过在迭代的每个步骤上执行
%
,我可以使用
Int
而不是
BigInt
,这同样节省了内存和执行时间。3) 通过执行
BigInt(10)^power
可以在每次迭代中执行幂运算,这是非常昂贵的。我只是做乘法运算,这要便宜得多。最后4)
Dict
lookup使我的算法为O(n),而你的算法为O(n^2),这是一个巨大的差异。如果你发布更新的代码,我可以查看它并对差异进行评论。