在Matlab中计算[a1 a2 a3 ... an]的所有二元和 [英] Calculating all two element sums of [a1 a2 a3 ... an] in Matlab
问题描述
上下文:我正在使用Matlab来处理Project Euler 问题23 ,以练习我几乎不存在的编程技巧。
我的问题:
现在我有一个大约6500个数字(范围从12到28122)元素并且想要计算所有的两个元素的总和。这就是我只需要每一个总和的一个实例,所以计算了a1 + an就没有必要计算a + a1。
编辑澄清:这包括和a1 + a1,a2 + a2,...,an + an。
问题是这太慢了。
问题具体限制:
这是一个给定的总和28123或以上没有必要计算,因为这些不能用于进一步解决问题。
我的方法:
AbundentNumberSumsRaw = [];
for i = 1:3490
AbundentNumberSumsRaw = [AbundentNumberSumRaw AbundentNumbers(i)+ AbundentNumbers(i:end);
end
这个工作非常可怕:p
我的评论:
我敢肯定,增量增加矢量AbundentNumbersRaw是不好的编码,因为这意味着内存使用量会不必要地激增。我还没有这样做,因为a)我不知道什么大小的矢量预先分配和b)我不能想出一种方法来注入到AbundentNumbersRaw有序的方式,而不使用一些丑陋的看起来嵌套
for i = 1:3490低于元素的数量,因为我检查并查看了索引高于3490的所有数字我很确定我的主要问题是,该程序需要做大量的向量AbundentNumbersRaw增量增加。
任何和所有的帮助和建议将不胜感激:)
干杯
Rasmus
假设
a = 28110 * rand(6500,1)+12;
然后
sums = [
a(1)+ a(1:end)
a(2)+ a(2:end)
...
];
是您正在计算的值。
您也声明其值超过28123的和应被丢弃。
这可以概括如下:
%计算所有2 - 元素和不重复
C = arrayfun(@(x)a(x)+ a(x:end),1:numel(a),'uniformoutput',false);
C = cat(1,C {:});
%放弃超过阈值的金额
C(C> 28123)= [];
或使用循环
%计算所有没有重复的2元素和
E = cell(numel(a),1);
for ii = 1:numel(a)
E {ii} = a(ii)+ a(ii:end);结束
E = cat(1,E {:});
%放弃超过阈值的总和
E(E> 28123)= [];
简单的测试显示 arrayfun
比循环,所以我会去 arrayfun
选项。
Context: I'm working on Project Euler Problem 23 using Matlab in order to practice my barely existing programming skills.
My Problem:
Now I have a vector with roughly 6500 numbers (ranging from 12 to 28122) as elements and want to calculate all the two element sums. That is I only need one instance of every sum, so having calculated a1 + an it's not necessary to calculate an + a1.
Edit for clarification: This includes the sums a1+a1, a2+a2,..., an+an.
The problem is that this is much too slow.
Problem specific constraints:
It's a given that sums 28123 or over aren't necessary to calculate, since those can't be used to solve the problem further.
My approach:
AbundentNumberSumsRaw=[];
for i=1:3490
AbundentNumberSumsRaw=[AbundentNumberSumRaw AbundentNumbers(i)+AbundentNumbers(i:end);
end
This works terribly :p
My Comments:
I'm pretty sure that incrementally increasing the vector AbundentNumbersRaw is bad coding, since that means memory usage will spike unnecessarily. I haven't done so, since a) I don't know what size vector to pre-allocate and b) I couldn't come up with a way to inject the sums into AbundentNumbersRaw in a orderly manner without using some ugly looking nested loops.
"for i=1:3490" is lower than the numbers of elements simply because I checked and saw that all the resulting sums for numbers whose index are above 3490 would be too large for me to use anyway.
I'm pretty sure my main issue is that the program need to do a lot of incremental increases of the vector AbundentNumbersRaw.
Any and all help and suggestions would be much appreciated :)
Cheers
Rasmus
Suppose
a = 28110*rand(6500,1)+12;
then
sums = [
a(1) + a(1:end)
a(2) + a(2:end)
...
];
is the calculation you're after.
You also state that sums whose value goes over 28123 should be discarded.
This can be generalized like so:
% Compute all 2-element sums without repetitions
C = arrayfun(@(x) a(x)+a(x:end), 1:numel(a), 'uniformoutput', false);
C = cat(1, C{:});
% discard sums exceeding threshold
C(C>28123) = [];
or using a loop
% Compute all 2-element sums without repetitions
E = cell(numel(a),1);
for ii = 1:numel(a)
E{ii} = a(ii)+a(ii:end); end
E = cat(1, E{:});
% discard sums exceeding threshold
E(E>28123) = [];
Simple testing shows that arrayfun
is somewhat faster than the loop, so I'd go for the arrayfun
option.
这篇关于在Matlab中计算[a1 a2 a3 ... an]的所有二元和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!