Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图为Erlang中的Euler#14项目找到更快的解决方案_Erlang - Fatal编程技术网

试图为Erlang中的Euler#14项目找到更快的解决方案

试图为Erlang中的Euler#14项目找到更快的解决方案,erlang,Erlang,我试图为欧拉计划的问题14写一个解决方案。我跑得最快的——不是下面的那个——跑了58秒左右。我发现使用谷歌搜索的最快速度大致如下: %% ets:delete(collatz) (from shell) deletes the table. -module(euler) . -export([problem_14/1]) . collatz(X) -> case ets:lookup(collatz, X) of [{X, Val}] -> Val ; []

我试图为欧拉计划的问题14写一个解决方案。我跑得最快的——不是下面的那个——跑了58秒左右。我发现使用谷歌搜索的最快速度大致如下:

%% ets:delete(collatz) (from shell) deletes the table.

-module(euler) .
-export([problem_14/1]) .

collatz(X) ->
  case ets:lookup(collatz, X) of
    [{X, Val}] -> Val ;
    []         -> case X rem 2 == 0 of
                    true  ->
                      ets:insert(collatz, {X, Val = 1+collatz(X div 2)} ) ,
                      Val ;
                    false ->
                      ets:insert(collatz, {X, Val = 1+collatz(3*X+1)} ) ,
                      Val
                  end
  end .

%% takes 10 seconds for N=1000000 on my netbook after "ets:delete(collatz)".
problem_14(N) ->
  case ets:info(collatz) of
    undefined ->
      ets:new(collatz, [public, named_table]) ,
      ets:insert(collatz,{1,1}) ;
    _         -> ok
  end ,
  lists:max([ {collatz(X), X} || X <- lists:seq(1,N) ]) .
%%%ets:delete(collatz)(从shell)删除表。
-模块(欧拉)。
-出口([问题14/1])。
科拉兹(X)->
案例ets:查找(collatz,X)
[{X,Val}]->Val;
[]->情况X rem 2==0
正确->
插入(collatz,{X,Val=1+collatz(X div 2)}),
瓦尔;
错误->
插入(collatz,{X,Val=1+collatz(3*X+1)}),
瓦尔
结束
结束。
%%在“ets:delete(collatz)”之后,我的上网本上N=1000000需要10秒。
问题14(N)->
案例ets:信息(collatz)
未定义->
ets:新(collatz,[公共,命名为_表]),
ets:插入(collatz,{1,1});
_->好的
完,,

列表:max([{collatz(X),X}| X我已经将代码的速度提高了一点:将ets指定为
ordered_set
,使用逐位操作并实现了尾部递归函数
max_size_index
,而不是将所有结果收集到列表中,然后迭代以找到最大值(如我们的代码中所示)

在shell中测试-您的模块
euler
和我的模块
collatz
()


加速的最后一个技巧——大间隔可以拆分为更小的间隔,并为每个小间隔并行生成计算(在其他节点上)一般来说,原始CPU绑定操作不是Erlang的强度。正如你注意到的,问题是数据被拷贝到ETS表中。中央ETS表还有一个优点,它也锁定了原子更新。如果你想,你可以很容易地得到更多的内核来解决这个问题。你不会接近C++或C SLU的速度。尽管如此


这类问题的另一个问题是可变性因此,你不能指望用一个短暂的哈希表或一个数组来打败一个C++解决方案,它可以存储它运行的百万条条目。你可以试试<代码>数组>代码>模块,但是我怀疑它会更快。< /P>尽管有1000000个整数,但不需要将它们全部计算为1个。经常出现。例如,13和80的步骤几乎相同。@halfelf,在有问题的代码中,
ets
表用于记忆,因此“路径”的相同部分不会计算两次。Erlang使用任意精度的整数,不是吗?如果使用了,使用本机64位整数类型可能会带来很大的加速。另一点,您将大量数字
>1000000
放入查找表(1168611)。只有46675个被再次查找。在正确阅读手册的同时,只记下
n的值可能会更快。我发现在每个ets上都复制了:插入对象。所以我想这是主要的瓶颈。您的版本在这里需要12秒。但我想,由于每次调用ets:insert都会复制对象,ets只是如果你在一秒钟内需要数百万次插入,情况就不是这样了……对我来说,问题14是迄今为止我找不到快速答案的第一个问题。所以我更担心这是我的错。(顺便说一句,我找到的使用数组的解决方案并没有更快。)
-module(collatz).
-compile(export_all).

size(1, _) ->
        1;
size(N, Hashset) ->
        case ets:lookup(Hashset, N) of
                [{N, Size}] ->
                        Size;
                [] ->
                        Size  = 1 + size( next(N), Hashset ),
                        ets:insert(Hashset, {N, Size}),
                        Size
        end.

next(N) when N band 1 == 0 ->
        N bsr 1;
next(N) ->
        (N bsl 1)+N+1.

max_size_index(1, _Hashset, {Index, MaxSize}) ->
        {Index, MaxSize};
max_size_index(N, Hashset, {Index, MaxSize}) ->
        CurrSize = size(N, Hashset),
        case CurrSize > MaxSize of
                true ->
                        max_size_index(N-1, Hashset, {N, CurrSize});
                false ->
                        max_size_index(N-1, Hashset, {Index, MaxSize})
        end.

problem_14(N) ->
        Hashset = ets:new(collatz_count, [public, ordered_set]),
        max_size_index(N, Hashset, {1,1}).
1> c(euler).
{ok,euler}
2> 
2> timer:tc(euler, problem_14, [1000000]). 
{4039838,{525,837799}}
3> 
3> c(collatz).
{ok,collatz}
4> 
4> timer:tc(collatz, problem_14, [1000000]). 
{2824109,{837799,525}}