2010-04-22 116 views
50

假設我有下面的矩陣:獲取n個最大元素的索引以矩陣

01 02 03 06 
03 05 07 02 
13 10 11 12 
32 01 08 03 

我想頂端5元素的索引(在這種情況下,32個,13,12,11 ,10)。在MATLAB中做到這一點最乾淨的方法是什麼?

+2

一個澄清:你想怎麼處理重複的元素?例如,如果數字32出現了7次,您是否想要獲得全部7個數字的索引,或者只有5個索引,或者只有1個索引,然後是下4個最大元素的索引? – gnovice 2010-04-22 16:26:37

+1

@Eric Leschinski請不要爲標題添加標籤,社區沒有必要也不會泄氣(請參閱[此主題的官方回覆的此meta貼子](http://meta.stackexchange.com/a/) 5069/151385)) – 2013-01-18 07:33:54

回答

72

有幾種方法可以做到這一點,取決於你想如何處理重複的值。下面是找到指數的5倍最大的值(其中可能包括重複值)的解決方案:

[sortedValues,sortIndex] = sort(A(:),'descend'); %# Sort the values in 
                %# descending order 
maxIndex = sortIndex(1:5); %# Get a linear index into A of the 5 largest values 

下面是找到5個大獨特價值的解決方案,然後尋找等於這些值的所有元素:

sortedValues = unique(A(:));   %# Unique sorted values 
maxValues = sortedValues(end-4:end); %# Get the 5 largest values 
maxIndex = ismember(A,maxValues);  %# Get a logical index of all values 
             %# equal to the 5 largest values 
+1

其實,沒有必要去做gnovice構成的最後一步。排序的第二個輸出是排序的標籤列表。因此,這些選定值的索引由排序中的相應標籤給出。如果您希望按照一對下標進行索引,請調用ind2sub。 – 2010-04-22 16:27:45

+0

@woodchips:很好。我正在按照您的意見改變它,並且以另一種方式添加另一個選項來處理重複的值。 – gnovice 2010-04-22 16:37:45

+3

這種方法對於小矩陣可能是最乾淨的,但對於大矩陣來說,顯然是次最優的,因爲按照「非Matlab方式」進行排序時,像O(N * log(N))這樣的尺度將像O(N)那樣縮放。 – Adrien 2010-04-22 16:49:45

15

如果你有一個相當大的數組,並且只需要少數幾個元素。這將是我的解決方案。

Arraycopy = Array; 
for j = 1:n 
    [a, Index(j)] = max(Arraycopy); 
    Arraycopy(Index(j)) = -inf; 
end 
maximumValues = Array(Index); 

我認爲它應該比排序解決方案更快,更少的RAM要求。

+2

只有在n個最大元素大於0的情況下才有效。否則,用min(Arraycopy,...)替換0。 – Unapiedra 2012-12-14 11:45:34

7

你也可以在matlabcentral上找到matlab問題的好答案。在搜索相同的東西時,我發現了一個很好的mex實現。

這是Bruno Luong用C-MEX實現的部分快速排序算法完成的。複雜度爲O(n + k.log(k)),其中n是數組的大小,k是要選擇的元素的數量。對於大尺寸輸入,它比SORT或MIN/MAX的多次調用更快。多維能力支持

http://www.mathworks.com/matlabcentral/fileexchange/23576-minmax-selection

相關問題