2016-04-15 3 views
0

Ich summiere Elemente des Arrays und speichere es im Wörterbuch. Schlüssel entspricht der Summe der Elemente in Array ohne Element mit index == Schlüssel. Ich versuche es als One-Liner zu machen. Dies ist nur das vereinfachte Beispiel meines Codes, um zu verstehen, was ich tun möchte.Julia: Summe der Elemente im Array außer Element entsprechend dem gewählten Index

Code:

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

Ich versuchte deleteAt mit!

sum(deleteat!(b, k)) 

Manchmal gibt es Bounds Fehler so möchte ich mit einer besseren Idee kommen, aber bisher kein Ergebnis.

Danke.

+2

Wie wäre es, alle Elemente hinzufügen und dann die, die Sie nicht wollen, subtrahieren aus? (Hinweis dass die Summe aller Elemente dasselbe ist, welches Element auch immer verwendet wird. Wenn Sie dies mehrmals tun, können Sie die Berechnung speichern, indem Sie die Summe nur einmal ausführen. –

+0

Ihr so Lösung ist gut, aber nicht für mein wirkliches Problem anwendbar. Der obige Code dient nur dazu, zu verstehen, was ich erreichen möchte. Ich möchte den echten Code hier nicht posten. –

+1

Es ist allgemein wahr, dass (Summe aller Elemente außer einem bei Index k) = (Summe aller Elemente) - (Element bei Index k), abgesehen von numerischen Problemen (z. B. wenn das Element bei Index k ist enorm und Sie ' arbeitet in Gleitkomma-Gleitkomma-Gleitkomma). –

Antwort

2

Die Lösung oben, das heißt:

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

denke ich, dass O sein (n^2), weil es einen Vektor der Länge a-Konstrukte, um ohne das Element bei j zu summieren, und tut diese Länge (a) mal, um den Ergebnisvektor zu konstruieren.

Hier ist meine erste Lösung (die O (n) sein sollte, n = Länge (a))

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

und hier ist eine andere Lösung (auch O (n)), unter Verwendung von Array-Operatoren.

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

Hier sind meine Benchmark-Ergebnisse, nachdem sie mit einem Vektor z erstellen: z = rand(1:100000,1000) Wie Sie sehen können, der am schnellsten ist meine erste Lösung, mit dem expliziten Array Verständnis (es geht um 1000x schneller als die Lösung, die zuvor in dem gegebenen Kommentare, denn es ist O (n) anstelle von O (n^2) und n == 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 
Verwandte Themen