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