在Matlab中查找最小元素的索引

5

这里我有两个矩阵,一个表示成本,另一个确定何时进行比较。

cost =      [0.2 0.0 0.3; 0.4 0 0; 0.5 0 0];
available = [1   1   0  ; 1   0 0; 0   0 0];
available = logical(available);

我希望能够获得费用矩阵中最小可用元素的索引,这种情况下将比较 0.2, 0.00.4 并返回 0.0 的索引,即在费用矩阵中为 (1, 2)4

我尝试过:

mul = cost .* available;     % Zero if not available, but I can't know if it is zero because cost is zero
mul(~mul) = nan;             % Set zero to be NaN
[minVal, minId] = min(mul)

这将有助于获得最小的非零成本,但如果存在可用的零元素,则会出现错误。

那么有更好的方法吗?


3
离题了:您应该避免像函数一样命名变量(例如min)。 - Eitan T
1个回答

2

以下是两种可能的解决方案。两种方案都涉及将所有不可用成本转换为Inf

%#Set up an example
Cost =      [0.2 0 0.3; 0.4 0 0; 0.5 0 0];
Available = [1   1   0; 1   0 0; 0   0 0];

%#Transform non-available costs to Inf
Cost(Available == 0) = Inf;

%#Obtain indices using find
[r, c] = find(Cost == min(min(Cost)))

%#Obtain linear indices and convert using ind2sub
[~, I1] = min(Cost(:));
[r2, c2] = ind2sub(size(Cost), I1);

两种解决方案仅在不存在唯一最小值的情况下返回第一个最小值。此外,如果所有可用成本都是Inf,则该方法将失败(但我猜如果您的所有成本都是无限大,那么您会有更大的问题...)。

我进行了一些速度测试,第二种方法无论Cost的维度如何,都明显更快,因此应严格优先选择它。此外,如果您只需要线性索引而不是下标索引,则可以省略对ind2sub的调用。但是,这并不能极大地提高效率,因此如果您偏好下标索引,则应使用它们。


我想这不太对。min(cost(available)); 返回的是 cost(available) 返回的新矩阵中的最小 ID,这种情况下是 3。但我想要的是 cost 矩阵中的 ID,应该是 4。 - Ovilia
第一个最小元素的索引就足够了。 - Ovilia
非常感谢!但是我认为使用find函数来获取id并不是很高效。我会改用[min, minId]=min(Cost(:)) - Ovilia
1
@Ovilia,那只会得到线性索引,而不是下标索引。如果你想要下标索引,你需要在其中调用sub2ind函数。我还在进行一些速度测试,并很快更新我的答案。 - Colin T Bowers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接