Sort elements of matrices

Hi, do you have any idea on how to sort the elements of 4 matrices (here called "groups"), as shown in the picture?
Some explanation: the system is composed of 4 groups, which can be represented by 4 matrices, with different number of rows but same number of columns (i.e. 5x4, 4x4, 3x4, 2x4). Every element is labelled with a letter and each column contains the same set of letters {'A','B','C','D','E','F','G','H','I','L','M','N','O','P'}. As we can see from the figure, the elements with the same label are connected by a line, forming a sort of chain (please see from left to right or from right to left). Some of these chains stay within each group, while other ones connect different groups.
My goal would be to sort the elements in each group as follows:
  1. If all the elements with the same label/name (e.g. 'A A A A' or 'N N N N', etc..) lie within the same group, i.e. in the same matrix, but in different rows, sort them in one row.
  2. If some elements with the same label/name (e.g. 'B B B B' or 'I I I I', etc..) are shared between two different groups/matrices, move those elements towards the "external" rows of the respective matrices, i.e. those rows which are the closest to the neighbouring groups/matrices.
INPUT and OUTPUT:
IN = {
{'A','A','C','A';
'B','B','A','C';
'C','C','E','D';
'D','D','D','I';
'E','E','I','E'}
{'F','F','F','F';
'G','G','G','B';
'H','H','B','M';
'I','I','H','H'}
{'L','L','N','N';
'M','M','M','G';
'N','N','P','L'}
{'O','O','L','O';
'P','P','O','P'}
};
OUT= {
{'A','A','A','A';
'C','C','C','C';
'D','D','D','D';
'E','E','E','E';
'B','B','I','I'}
{'I','I','B','B';
'F','F','F','F';
'H','H','H','H';
'G','G','G','M'}
{'M','M','M','G';
'N','N','N','N';
'L','L','P','L'}
{'P','P','L','P';
'O','O','O','O'}
};

6 Commenti

Jon
Jon il 23 Set 2020
Can you assume that any letter is shared by at most two groups?
Sim
Sim il 23 Set 2020
Modificato: Sim il 23 Set 2020
Hi Jon! Actually, a letter can be shared up to 3 groups, and it will appear always in different columns (not shown in this example, where I tried to simplify my system to jumps between 2 groups). In general a letter can just stay within one group or shared by two groups or max by three groups. Also, if helpful, another info about labels/letters: in each of the 4 columns there are not duplicate letters. To any column we will look at, we won't see the same letter twice or more. In other words, no repeated letters in the same column.
Jon
Jon il 23 Set 2020
If a letter is shared by more than 2 groups then how do you define nearest/external rows?
Sim
Sim il 23 Set 2020
Modificato: Sim il 23 Set 2020
Ah right.. let's consider group 1, group 2 and group 3 as example and therefore a chain crossing from group 1 to group 3. About groups 1 and 3, the idea of "nearest/external" row would be the same as previously described. Instead, about group 2, I would put the chain's element as close as possible to the "nearest/external" rows of group 2. Either to the "nearest/external" top row, or the the "nearest/external" bottom row of group 2. I would just select the "nearest/external" bottom row. Hope it is clear and thanks a lot for your help!
Adam Danz
Adam Danz il 23 Set 2020
This looks like homework to me in which case you should show what you've tried so we can help you get over the edge rather than propose the entire solution for you.
Sim
Sim il 23 Set 2020
Modificato: Sim il 23 Set 2020
Oh Yes, I will write my attempts here :)
Meanwhile I accepted the David Hill answer, since it actually does what I asked for in this post :)

Accedi per commentare.

 Risposta accettata

David Hill
David Hill il 23 Set 2020
Modificato: David Hill il 23 Set 2020
Might be a better way, but here it is for the example. If shared with multiple groups, as stated above, I don't know what you want.
function A = groupSort(A)
a=ismember(A{1},A{2});
A{1}=reshape([sort(A{1}(~a));A{1}(a)],4,[])';
for k=2:length(A)-1
b=ismember(A{k},A{k-1});
a=ismember(A{k},A{k+1});
A{k}=reshape([A{k}(b);sort(A{k}(~(a+b)));A{k}(a)],4,[])';
end
A{end}=reshape([A{end}(ismember(A{end},A{end-1}));sort(A{end}(~ismember(A{end},A{end-1})))],4,[])';
Changed the input to cell of matrices:
IN = {
['A','A','C','A';
'B','B','A','C';
'C','C','E','D';
'D','D','D','I';
'E','E','I','E']
['F','F','F','F';
'G','G','G','B';
'H','H','B','M';
'I','I','H','H']
['L','L','N','N';
'M','M','M','G';
'N','N','P','L']
['O','O','L','O';
'P','P','O','P']
};

3 Commenti

Hi David, thanks a lot! Very grateful!
....I was trying with my data, but for some reason the reshape does not work... I would need to check it...
Well, actually what I want/need is something a bit more complicated (just in case I attach here the IN.mat file), where the columns of all groups might have a different length (differently by my posted example where the columns lengths were fixed for each group), i.e.:
IN =
4×4 cell array
{39×1 cell} {39×1 cell} {39×1 cell} {41×1 cell}
{15×1 cell} {15×1 cell} {24×1 cell} {10×1 cell}
{ 7×1 cell} { 7×1 cell} { 3×1 cell} { 6×1 cell}
{ 6×1 cell} { 6×1 cell} { 1×1 cell} {10×1 cell}
where Group 1 is:
{39×1 cell} {39×1 cell} {39×1 cell} {41×1 cell}
Group 2 is:
{15×1 cell} {15×1 cell} {24×1 cell} {10×1 cell}
Group 3 is:
{ 7×1 cell} { 7×1 cell} { 3×1 cell} { 6×1 cell}
Group 4 is:
{ 6×1 cell} { 6×1 cell} { 1×1 cell} {10×1 cell}
P.S: in the attached file the names are 'A1', 'A2', 'A3', ..., 'A67'
David Hill
David Hill il 23 Set 2020
How can the different groups have columns with a different number of rows? This does not match your example.
Sim
Sim il 23 Set 2020
Modificato: Sim il 23 Set 2020
Yes, true, I was just trying to simplify the problem.. and then trying to get the solution to my exact case......Meanwhile, I accepted your answer, thanks a lot.....However, I will try to adapt your solution to the case with different number of rows and I will try to post it here (its gonna take a while, since I am currently multitasking)..... :)

Accedi per commentare.

Più risposte (0)

Categorie

Richiesto:

Sim
il 23 Set 2020

Modificato:

Sim
il 23 Set 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by