2016-04-15 2 views
0

Я суммирую элементы массива и сохраняю его в словаре. Ключ соответствует сумме элементов в массиве, исключающем элемент с index == ключ. Я пытаюсь сделать это как однострочный. Это просто упрощенный пример моего кода для понимания того, что я хочу делать.Julia: сумма элементов в массиве кроме элемента, соответствующего выбранному индексу

Код:

a = [1, 2, 3, 4] 
b = [1, 2, 3, 4] 
result = [k => sum(b) for k=a] 

Я попытался с помощью deleteat!

sum(deleteat!(b, k)) 

Иногда это дает Bounds ошибку поэтому я хочу, чтобы придумать лучшую идею, но до сих пор нет результатов.

Спасибо.

+2

Как насчет добавления всех элементов, а затем вычитая от тот, который вы не хотите? (Примечание что сумма всех элементов одинакова, какой бы элемент вы ни использовали, поэтому, если вы делаете это несколько раз, вы можете сэкономить вычисления, выполнив сумму только один раз.) –

+0

Это хорошо, но не применимо для моей реальной проблемы. Код выше предназначен только для понимания того, чего я хочу достичь. Я просто не хочу публиковать настоящий код здесь. –

+1

Общепризнано, что (сумма всех элементов, кроме одного по индексу k) = (сумма всех элементов) - (элемент с индексом k), помимо численных вопросов (например, если элемент с индексом k огромен, re работает с плавающей запятой с ограниченной точностью). –

ответ

2

Раствор выше, то есть:

f(a) = [sum([i==j ? zero(eltype(a)) : a[j] for j=1:length(a)]) for i=1:length(a)] 

Я считаю, что будет O (N^2), так как он создает вектор длины а, для того, чтобы подвести без элемента на J, и делает эта длина (а) раз для построения вектора результата.

Вот мое первое решение (которое должно быть О (п), п = длина (а))

g(a) = let s = sum(a) ; [ s-v for v in a ] end 

и вот другое решение (также О (п)), с использованием операторов массива.

h(v) = fill(sum(v), length(v)) - v 

Вот мои результаты тестов, после создания вектора г с: z = rand(1:100000,1000) Как вы можете видеть, самые быстрое мое первое решение, с явным пониманием массива (речь идет о 1000x быстрее, чем решение данного ранее в комментарии, потому что это O (п) вместо O (N^2), п == 1000.

julia> @benchmark f(z) 

================ Benchmark Results ======================== 
    Time per evaluation: 2.59 ms [1.86 ms, 3.32 ms] 
Proportion of time in GC: 19.08% [3.56%, 34.59%] 
     Memory allocated: 7.79 mb 
    Number of allocations: 3003 allocations 
     Number of samples: 100 
    Number of evaluations: 100 
Time spent benchmarking: 0.34 s 


julia> @benchmark g(z) 
================ Benchmark Results ======================== 
    Time per evaluation: 1.77 μs [1.74 μs, 1.79 μs] 
Proportion of time in GC: 8.65% [7.34%, 9.95%] 
     Memory allocated: 7.97 kb 
    Number of allocations: 3 allocations 
     Number of samples: 8201 
    Number of evaluations: 4959001 
     R² of OLS model: 0.952 
Time spent benchmarking: 8.88 s 


julia> @benchmark h(z) 
================ Benchmark Results ======================== 
    Time per evaluation: 2.98 μs [2.94 μs, 3.03 μs] 
Proportion of time in GC: 10.54% [9.05%, 12.02%] 
     Memory allocated: 15.92 kb 
    Number of allocations: 5 allocations 
     Number of samples: 7601 
    Number of evaluations: 2799801 
     R² of OLS model: 0.951 
Time spent benchmarking: 8.41 s 
Смежные вопросы