Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.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
Performance 如何使我的代码更快?_Performance_Matlab - Fatal编程技术网

Performance 如何使我的代码更快?

Performance 如何使我的代码更快?,performance,matlab,Performance,Matlab,我写这段代码是为了解决问题4——ProjectEuler,但它花费了我太长的时间来给出答案 有什么窍门可以让它更快吗 function S=Problem4(n) tic Interval=10^(n-1):10^(n)-1; [Product1,Product2]=meshgrid(Interval); Func=@(X,Y) X*Y; Temp=cell2mat(arrayfun(Func,Product1,Product2,'UniformOutput',false)); Palindro

我写这段代码是为了解决问题4——ProjectEuler,但它花费了我太长的时间来给出答案

有什么窍门可以让它更快吗

function S=Problem4(n)
tic
Interval=10^(n-1):10^(n)-1;
[Product1,Product2]=meshgrid(Interval);
Func=@(X,Y) X*Y;
Temp=cell2mat(arrayfun(Func,Product1,Product2,'UniformOutput',false));
Palindrome=@(X) all(num2str(X)==fliplr(num2str(X)));
Temp2=unique(Temp(:));
S=max(Temp2(arrayfun(Palindrome,Temp2)));
toc
end
大约需要39秒


任何帮助都将不胜感激。

我鼓励您查看此链接(),同时,我建议您使用“缓存/内存”功能,当您进行迭代计算时,您可以存储参数和答案,因此下次使用相同的参数时,您只需返回存储的答案,在过程中跳过一些计算

希望能有所帮助,如果您还有疑问,请告诉我。

来源:

最大回文乘积
问题4

回文数字的两种读取方式相同。由两个两位数的乘积构成的最大回文是9009=91×99

查找由两个3位数字的乘积构成的最大回文

我将提供另一种方法,而不是分析代码,您可能会发现这种方法很有用。它使用矢量化,避免使用可能很慢的
arrayfun
和匿名函数:

[n1, n2] = ndgrid(100:999); %// all combinations of 3-digit numbers
pr = n1(:).*n2(:); %// product of each combination
de = dec2base(pr, 10); %// decimal expression of those products
sm = pr<1e5; %// these have 5 figures: initial digit "0" should be disregarded
pa = false(1,numel(pr)); %// this will indicate if each product is palindromic or not
pa(sm) = all(de(sm,2:end) == fliplr(de(sm,2:end)), 2); %// 5-figure palindromic
pa(~sm) = all(de(~sm,:) == fliplr(de(~sm,:)), 2); %// 6-figure palindromic
result = max(pr(pa)); %// find maximum among all products indicated by pa
[n1,n2]=ndgrid(100:999);%//3位数字的所有组合
pr=n1(:).*n2(:);%//每种组合的乘积
de=dec2base(pr,10);%//这些乘积的十进制表达式

sm=pr这里只给出了部分答案,但使用字符串处理数字往往会导致性能大幅下降

这里有一个函数,它甚至可以在一行中执行两次

首先,通过将中间结果保存在变量中,尝试删除一个。如果这样可以节省大量时间,那么可能也值得删除另一个


以下是几年前我自己的方法。它不是那么伟大,但也许它能激励你

请注意,它确实使用了
num2str
,但只使用了一次,并且一次在所有相关的数字上使用。在代码中使用
arrayfun
,它基本上在内部使用循环,可能会导致对
num2str
的多次调用

clear
field = (100:999)'*(100:999);
field = field(:);
fieldstr = num2str(field);
idx = fieldstr(:,1) == fieldstr(:,end);
idx2 = fieldstr(:,2) == fieldstr(:,end-1);
idx3 = fieldstr(:,3) == fieldstr(:,end-2);
list = fieldstr(idx & idx2 & idx3,:);
listnum = str2num(list);
max(listnum)
一些讨论和解决方案代码 由于您正在查找
最大值
回文,因此在收集了具有该
间隔
的可能产品编号后,对于
所有编号的每个可能的
位数
,您可以迭代查找可能的最大编号。因此,使用
n=3
,您将拥有从
10000
998001
的产品。因此,您可以先查找
6位
数字中的最大回文数,然后查找
5位
数字,依此类推。这种迭代方法的好处是,只要您拥有
max
编号,就可以
退出该函数。以下是实现讨论中提出的承诺的准则-

function S = problem4_try1(n)

Interval=10^(n-1):10^(n)-1; %// Define interval definition here

prods = bsxfun(@times,Interval,Interval'); %//'# Or Use: Interval'*Interval
allnums = prods(:);

numd = ceil(log10(allnums));        %// number of digits
dig = sort(unique(numd),'descend'); %// unique digits starting from highest one

for iter = 1:numel(dig)
    numd_iter = dig(iter);
    numd_iter_halflen = floor(numd_iter/2);
    
    all_crit = allnums(numd==numd_iter); %//all numbers in current iteration
    all_crit_dg = dec2base(all_crit,10)-'0'; %// separate digits for a 2D array

    all_curit_digits_pal = all_crit(all(all_crit_dg(:,1:numd_iter_halflen) == ...
        all_crit_dg(:,end:-1:end-numd_iter_halflen+1) ,2)); %// palindrome matches
    
    %// Find the max of palindrom matches and get out
    if ~isempty(all_curit_digits_pal)
        S = max(all_curit_digits_pal);
        return;                         %//  *** Get Outta Here!!
    end
end
关于代码本身的一些事情

  • bsxfun(@times,Interval,Interval')
    有效地获取产品值,这是您在
    Temp
    中获得的值,因此这必须非常有效,因为不必处理中间
    Product1
    Product2
  • 由于迭代性质,如果系统能够在开始时处理产品计算的预处理部分,那么对于较高的
    n
    ,它必须足够有效

  • 请描述问题,并解释代码背后的逻辑,确保检查并展示的输出您是否有机会尝试本页上发布的各种方法来解决您的问题?我们很想知道他们的表现如何!大约需要26.2秒。如果你找到一个技巧来移除字符串之间的转换(如@Luis现在删除的答案),它会减少到大约0.2秒。这是一个错误。我现在已经改正了+1对于你的答案,实际上我也使用字符串,但是一般来说,
    dec2base
    似乎是fasterNice链接,但是它似乎没有涵盖他的代码中的主要问题。存储或缓存计算不足以完全解决OP遇到的问题。我想我们的解决方案在使用
    dec2base
    all
    方面有相似之处,但是我认为我可以发布一个基于迭代的方法,并且还可以使用
    bsxfun
    避免
    ndgrid/meshgrid
    ,这必须更有效。希望一切都好@当然是迪瓦卡!我应该想到
    bsxfun
    function S = problem4_try1(n)
    
    Interval=10^(n-1):10^(n)-1; %// Define interval definition here
    
    prods = bsxfun(@times,Interval,Interval'); %//'# Or Use: Interval'*Interval
    allnums = prods(:);
    
    numd = ceil(log10(allnums));        %// number of digits
    dig = sort(unique(numd),'descend'); %// unique digits starting from highest one
    
    for iter = 1:numel(dig)
        numd_iter = dig(iter);
        numd_iter_halflen = floor(numd_iter/2);
        
        all_crit = allnums(numd==numd_iter); %//all numbers in current iteration
        all_crit_dg = dec2base(all_crit,10)-'0'; %// separate digits for a 2D array
    
        all_curit_digits_pal = all_crit(all(all_crit_dg(:,1:numd_iter_halflen) == ...
            all_crit_dg(:,end:-1:end-numd_iter_halflen+1) ,2)); %// palindrome matches
        
        %// Find the max of palindrom matches and get out
        if ~isempty(all_curit_digits_pal)
            S = max(all_curit_digits_pal);
            return;                         %//  *** Get Outta Here!!
        end
    end