2017-11-01 12 views
5

Tôi có một mảng A=[3, 5, 1, 2, 7, 9, 10, 2, 3] có độ dài length(A)=9 và một tập hợp S có chứa một tập con của các chỉ mục 1:9, ví dụ: S=Set([1, 3, 6, 8]). Tôi muốn tìm giá trị tối đa (giá trị và chỉ số) của A trên S. Tức là, tối đa là 9 và chỉ mục là 6.Làm cách nào để tìm chỉ mục tối đa trên tập con của các phần tử trong julialang?

tôi đã cố gắng để làm điều đó theo cách này

A = [3, 5, 1, 2, 7, 9, 10, 2, 3]; 
S = Set([1, 3, 6, 8]); 
B = [if i in S A[i] else 0 end for i in 1:length(A)]; 
findmax(B); 

nhưng tôi cảm thấy như có một cách tốt hơn và thông minh.

Trả lời

5

Làm thế nào?

julia> maximum((A[i],i) for i in S) 
(9, 6) 

Điều này dựa vào thực tế là các bộ dữ liệu được sắp xếp theo thứ tự từ điển. Điều này chỉ lặp lại trên tập hợp con, vì vậy nó sẽ nhanh hơn khi S có ít phần tử đáng kể hơn A.

maximum là lựa chọn tốt hơn so với findmax tại đây như Dan Getz đã chỉ ra.

+0

Nếu bạn quấn biểu thức bằng 'đầu tiên (...)' sau đó đầu ra là sạch hơn –

+2

hoặc chỉ sử dụng 'tối đa ((A [i], i) cho i trong S)' –

+0

Nếu tôi có nhiều tối đa và tôi muốn tìm tất cả, chúng ta vẫn có thể sử dụng cách tiếp cận của bạn? Giống như nếu 'A' bằng với' A = [3, 5, 9, 2, 7, 9, 10, 2, 9] 'và' S = Set ([1, 3, 6, 8]) '. Cách tiếp cận của bạn 'tối đa ((A [i], i) cho i trong S)' cho '(9, 6)' thay vì '(9, 3)' và '(9, 6)'. – Ribz

2

Nếu A sẽ không chứa các bản sao (hoặc ít nhất, tối đa là duy nhất), tôi muốn tìm ra sau dễ đọc hơn:

julia> i = findfirst(A, maximum(A[i] for i in S)) 
6 
julia> A[i], i 
(9, 6) 

Các maximum công trình trên một máy phát điện, vì vậy không nên có bộ nhớ trên không. Nếu S nhỏ, kích thước của A chiếm ưu thế và bạn vẫn phải duyệt qua điều đó.

+0

Xin hãy kiểm tra cái này 'A = [1, 1]; S = Set ([2]); i = findfirst (A, cực đại (A [i] đối với i trong S)); println ("tìm thấy $ ((A [i], i)) nhưng là i trong S? $ (i trong S)! ")'! – Liso

+0

@Liso Cảm ơn bạn đã chỉ ra điều đó. Tôi đã thêm một điều kiện tiên quyết. – phg

4

Đây là tiết hơn, nhưng trên máy tính của tôi khoảng 2.5x nhanh như các giải pháp máy phát điện (phiên bản 0.6):

function mymax(A, S) 
    val, ind = typemin(eltype(A)), -1 
    for i in S 
     val_ = A[i] 
     if val_ > val 
      val, ind = val_, i 
     end 
    end 
    return val, ind 
end 
+0

Tôi nhận được kết quả tương tự trên máy tính của tôi với 'S' và' A' được đưa ra trong OP. Thay vào đó, nếu tôi tạo thành phần 'A' 10^4 và' S' 10^3 thì mã của bạn nhanh hơn 1.2 lần. (Ngoài ra 0.6) – gggg

+1

Có vẻ như một số chi phí cho máy phát điện, chúng phân bổ bộ nhớ, không giống như vòng lặp. Tôi tự hỏi nếu điều đó là không thể tránh khỏi. Máy phát điện rất mát mẻ, nó sẽ là tuyệt vời nếu họ cũng siêu nhanh. – DNF

1

Trong trường hợp có nhiều hơn mức tối đa bạn có thể làm:

function maximums(A,S) 
    maxvalue = maximum(A[i] for i in S) 
    (maxvalue, [i for i in S if A[i]==maxvalue]) 
end 

A = [3,3,3] 
S = Set([1,3]) 
maximums(A, S) # (3, [3, 1]) 

Nếu bạn muốn giữ gìn trật tự và Set là không cần thiết cho S thì bạn có thể sử dụng unique chức năng:

S = unique([1,3]) 
maximums(A, S) # (3, [1, 3]) 
Các vấn đề liên quan