Here I have two matrix, one indicating cost and the other determines when to take into comparison.
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);
I want to get the index of the min available element in the cost matrix, which in this case would compare 0.2
, 0.0
and 0.4
and return the index of 0.0
, which is (1, 2)
or 4
in the cost matrix.
I tried
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)
This will help to get the min non-zero cost but if there exists zero elements which are available, it would be wrong.
So is there a better way to do so?
Here are two possible solutions. Both essentially involve converting all non-available costs to 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);
Both solutions will only return the first minimum value in the instance that there is not a unique minimum. Also, the method will fail in the perverse case that all the available costs are Inf
(but I guess you've got bigger problems if all your costs are infinite...).
I've done a few speed tests, and the second method is definitely faster, no matter what the dimensions of Cost
, so should be strictly preferred. Also, if you only want linear indices and not subscript indices then you can of course drop the call to ind2sub
. However, this doesn't give you huge savings in efficiency, so if there is a preference for subscript indices then you should use them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With