My code breaks if there are two equal values within the data matrix, how do I tell it to select the first one it comes across?
1 view (last 30 days)
Show older comments
I have a code that runs through a price matrix and finds minimum, gets coordinate information, finds the corresponding locations within the Supply and Demand vectors, allocates from those two, and then repeats to find the next minimum. i.e. if 1.6 is the minimum and its location is [3,2] it would draw from supply location R[1,3] and demand location D[1,2], however in this case it eventually encounters two 17s within the matrix, and it outputs [1 1;3 4] as the coordinates which causes the math down later in the code to break. How would I tell the it to just pick the first minimum and then later come back to the other one in the next loop? I had previously posted this but did so in such a poor fashion no one knew what was going on, my apologies for that.
%Insert Cost Matrix, Supply & Demand vectors%
%%!!!! At present code will not work with equal values present within the
%%matrices, add decimal points to make not equal
%%i.e. if 17,16,17 would become 17,16,17.0000001
%%with enought points the final answer will be rounded
CostsMtx=[16,18,17,20,17;25,27,29,32,28;1.5,1.6,1.7,2,1.8;50,54,56,60,57;60,63,65,68,64];
supply=[800,600,1000,400,100];
demand=[870,435,725,464,406];
%%%%%%Below are definitions to tell when to stop%
mtxsz=size(CostsMtx);
n=numel(CostsMtx);
%%%Definers to create a looping edit matrix%
tmtx=CostsMtx;
res=zeros(mtxsz);
%%%%%%%%%
R=supply;
D=demand;
%%%Loop to extract minimum value, find corresponding Supply and Demand
%%%locations, evaluate and allocate then find next minimum and repeat until
%%%Supply and demand are depleted. The resolved allocations are summed
for i=1:n
x=min(tmtx(tmtx>0));
[Row,Col]=find(tmtx==x);
rm=min(R(1,Row));
dm=min(D(1,Col));
if R(1,Row)==0
tmtx(Row,Col)=0;
end
if D(1,Col)==0
tmtx(Row,Col)=0;
end
if rm<dm
res(Row,Col)=tmtx(Row,Col)*R(1,Row);
D(1,Col)=D(1,Col)-R(1,Row);
R(1,Row)=0;
tmtx(Row,Col)=0;
end
if dm<rm
display(tmtx(Row,Col));
res(Row,Col)=tmtx(Row,Col)*D(1,Col);
R(1,Row)=R(1,Row)-D(1,Col);
D(1,Col)=0;
tmtx(Row,Col)=0;
end
if dm==rm
res(Row,Col)=tmtx(Row,Col)*D(1,Col);
R(1,Row)=R(1,Row)-D(1,Col);
D(1,Col)=0;
tmtx(Row,Col)=0;
end
S=sum(res);
sr=sum(S);
end
%%%Displays summed allocation costs%
Solution=round(sr)
0 Comments
Accepted Answer
Walter Roberson
on 23 Jul 2017
Replace
x=min(tmtx(tmtx>0));
[Row,Col]=find(tmtx==x);
with
[x, idx] = min(tmtx(tmtx>0));
[Row, Col] = ind2sub(size(tmtx), idx);
3 Comments
Walter Roberson
on 23 Jul 2017
We as volunteers unfamiliar with this particular problem have no way of knowing what number would not be "very wrong".
I modified your code to try to do "reasonable" things in the case where duplicate values were found, working on all of the found rows or columns simultaneously, but unfortunately after a few steps my modified version gives an all-zero tmtx matrix, which is something your code does not allow for.
If you change your
[Row,Col]=find(tmtx==x);
to
[Row,Col]=find(tmtx==x, 1, 'last');
so that you get the last match then the result comes out as 62559 instead of the 62300 that you get if you use 'first' instead of 'last'.
Ah, I found the bug with my earlier change. To get the first, change
x=min(tmtx(tmtx>0));
[Row,Col]=find(tmtx==x);
to
x=min(tmtx(tmtx>0));
[Row,Col]=find(tmtx==x, 1, 'first');
However, as mentioned above, this is fragile, with choosing 'last' giving a different result, and that in turn suggests that there might possibly be a different sequence of choices that gives a lower (or higher) result still.
More Answers (0)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!