在Matlab中计算[a1 a2 a3 ... an]的所有二元和 [英] Calculating all two element sums of [a1 a2 a3 ... an] in Matlab

查看:224
本文介绍了在Matlab中计算[a1 a2 a3 ... an]的所有二元和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上下文:我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆