5

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?

1
  • 3
    Off-topic: you should refrain from naming variables like functions (for instance min). Commented Nov 11, 2012 at 12:45

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I suppose this is not quit right. min(cost(available)); returns the minId in a new matrix returned by cost(available), which in this case is 3. But I want the id in cost matrix, which should be 4.
Index of the first min element is enough.
Thank you very much! But I think using find to get the id is not very efficient. I'll use [min, minId]=min(Cost(:)) instead.
@Ovilia That will only get you the linear index, not the subscript index. You'll need a call to sub2ind in there also if you want the subscripts. I'm also doing a few speed tests and will update my answer soon.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.