MATLAB Answers

Choose a cell array that satisfy better some criteria

2 views (last 30 days)
luca
luca on 11 Oct 2019
Commented: luca on 14 Oct 2019
Given two arrays
A = [45 41 19 32 32 15 24 1 41 15 15 15 15];
B = [200 200 200 200 200 200 200 200 200 200 200 200 200];
I want to make the difference, substracting A from B and obtaining
C = [155 159 181 168 168 185 176 199 159 185 185 185 185];
Now I want to ordinate the cloumns of C and obtain a vector with column number from higher value to loerr one. Note for example that the highest value is 199, so column 8. then we have 185 so 6, 10, 11, 12,13 . At the end we will have an array we all the columns number from higher value to lower one
D = [8 6 10 11 12 13 3 7 4 5 2 9 1];
Now I want to create a vector from D that I will use to make comparison with other arrays. In particular I give weigth from 13 to 1, at all the values in D, creating E
E = [13 12 11 10 9 8 7 6 5 4 3 2 1];
Where 13 refers to element 8, 12 to element 6, 11 to element 10 and so on.
From array E we derive the number 13121110987654321, that we will use for comparison we other vector.
Now we have a cell array
VM = {[46 41 24 33 32 15 41 19 0 13 15 14 15]; [0 2 41 10 9 32 9 32 41 31 31 31 31];[13 10 19 3 2 41 0 20 41 41 41 41 41]}
For each cell of VM I want to do same, taking for example the first cell
VM{1,1}= [46 41 24 33 32 15 41 19 0 13 15 14 15];
I want to do thefollowing and ordinate the column from the higher to lower obttaining
F=[1 2 7 4 5 3 8 6 11 13 12 10 9]
As we can see the highest value is 46 so I put one in front. then 41 so I put 2.
Then I have to make comparison between F and E. for each element of F I wan to report how many values has that element in front of it in E. So for example, taking the first element of F: 1.
1 in E has 0 element in front of it. so I create a new vector G with 0 in front. element 2 has 2 element in front of it so I put 2. 7 has 6 element. 4 has 3 and so on
G = [0 1 6 3 4 2 7 5 10 12 11 9 9]
the array G give as a result the number 163427510121199, later we will compare this number with the one obtained in E.
Taking now the second cell
VM{1,2} = [0 2 41 10 9 32 9 32 41 31 31 31 31];
I obtain again
F = [3 9 6 8 10 11 12 13 4 5 7 2 1];
again
G = [2 8 5 7 9 10 11 12 3 4 6 1 0];
In this case we obtain a number 2857910111234610
The number obtained in each cell of VM has to be reported in a vector and
BB= [163427510121199, 2857910111234610, ...] and made a comparison with the one obtained from E: 13121110987654321.
As expected the one in E is the highest one. Now we want to give a weight to the one obtained in BB. Remember that the higher the better. the hogher value in BB will have a value of 200 (fixed) then going down to the ohter I want a value every time reduced by 3. so 200, 197, 194 and so on.
In thi case from BB we will have
HH = [197, 200 , ..].
So the main Idea is evertime to select the cell array in VM that summed to inital vector A, allow us to enhance the A quantity following the values in B, without producing more in one column with respect to the others.
SIMPLER SOLUTION ARE WELL ACCEPTED
May someone help me with the code?

  14 Comments

Bob Nbob
Bob Nbob on 11 Oct 2019
Mmm, ok, I think I see what you mean. Let me think about it over the weekend. I will get back to you if nobody else responds by then. Sorry for not having a more prompt solution.
luca
luca on 11 Oct 2019
No problem! Thanks for the help. If you need more info let me know ! I’m here

Sign in to comment.

Accepted Answer

Bob Nbob
Bob Nbob on 14 Oct 2019
Edited: Bob Nbob on 14 Oct 2019
Ok, here is what I have come up with. It will probably still need some tweaking, but you should be most interested in the calculation of BB. I don't know how else to get around the problem you had with numbers greater than 9, so I just compared the individual element locations, and found the smallest difference in positions. It's just a for loop, but written more nicely with arrayfun.
A = zeros(1,13);
while A < B % Loop through selection until A exceeds B. Can be changed to for loop of you want
C = B - A; % Get difference between A and B
[~,C] = sort(C,2,'descend'); % Determine descending order index of differences. Set to have biggest difference as #1 (Formerly D)
C(2,:) = [1:13]; % Add a relative position array (technically doesn't need to happen each loop (Formerly E)
for i = 1:size(VM,1) % Loop through different VM sets. Can be done with cells if you want, but I like matrices better
[~,tmp(i,:,1)] = sort(VM(i,:),2,'descend'); % Determine descending order index. Set to have biggest number as #1 (Formerly F)
tmp(i,:,2) = [1:13]; % Add a relative position array (Not previously created)
BB(i) = sum(abs(arrayfun(@(x) C(2,C(1,:)==x)-tmp(i,tmp(i,:,1)==x,2),C(1,:)))); % Compare relative positions of each element and find difference. Sum the values (Formerly G and some other things)
end % VM loop
A = A + VM(BB == min(BB),:); % Add values with smallest difference in positions to A. Loop begins again after this
end % A size check loop
The while loop ends when any element of A reaches or exceeds the relative element of B (i.e. when any element of A >= 200)
Also, note that I have VM as a 2D array, rather than a cell array. You can use the cell array you already have, just make sure you adjust the for loop indexing properly.

  5 Comments

Show 2 older comments
luca
luca on 14 Oct 2019
I'm studiyng your code. And yes it can works. But running it I ve seen how most of the time it doesn't work optimally.
To make it work in the best way we should give a weight to some value when the difference between B and A is high for some elements with respect to the others. in this case we should prefer the sequence that enhance that value. Do you think its possible to implement?
Bob Nbob
Bob Nbob on 14 Oct 2019
That's fair. It's definitely possible to implement something like that, but I don't have time to think through the logic thoroughly enough to provide you with a good solution. If you can write out the logic you want I can help you turn it into code.

Sign in to comment.

More Answers (0)

Products


Release

R2019b