How to deal with a vector containing numbers and characters?
4 views (last 30 days)
Show older comments
Having a vector of mixed numbers and characters like
M=['(1,3)',
'(5,4)',
'(9,7),(6,8)',
'(7,3)',
'(7,9),(2,4),(3,10)',
'(5,8)']
how can I compute the minimal set of numbers S such that each row of M has at least one number belonging to set S?
For the above simple example the answer is
S=[1 5 7]
However, I need a function that can compute the set S for M with any large size.
0 Comments
Accepted Answer
Stephen23
on 23 Aug 2018
Edited: Stephen23
on 24 Aug 2018
"how can I compute the minimal set of numbers S such that each row of M has at least one number belonging to set S?"
You could try my function mincoverset (attached). For small problems, like the one in your question, it will finish and return the set/s. For untractably large problems, like your .mat file data, you should set the first argument to limit how it will run for. When I tried it for ten minutes it had found several 359-element minimum cover sets:
>> S = load('M.mat');
>> M = S.M;
>> C = cellfun(@(s)sscanf(s,'(%d,%d),'),M,'uni',0);
>> Z = mincoverset(10/(60*24), C{:});
>> size(Z)
ans =
6 359
"For the above simple example the answer is S=[1 5 7]"
Actually I found six minimal cover sets for your example data:
>> M = {'(1,3)','(5,4)','(9,7),(6,8)','(7,3)','(7,9),(2,4),(3,10)','(5,8)'};
>> C = cellfun(@(s)sscanf(s,'(%d,%d),'),M,'uni',0);
>> Z = mincoverset(Inf, C{:})
Z =
1 5 7
3 5 9
3 5 7
3 5 6
3 5 8
3 4 8
An alternative method would be to represent the data in conjunctive normal form, and then convert to a disjunctive normal form:
9 Comments
Stephen23
on 28 Aug 2018
Edited: Stephen23
on 28 Aug 2018
@Hossein: cellfun supports a few special syntaxes (which are quite fast), where prodofsize is equivalent to the product of the size of the input array, i.e.:
cellfun(@(x)prod(size(x)),...)
or equivalently:
cellfun(@numel,...)
"I don't know how the number of permutations has been obtained? For example, how for 6 elements in C, the number of permutations is 384?"
The number of combinations (not permutations) is simply how many elements are in each vector within C, all multiplied together:
>> V = cellfun(@numel,C) % equivalent to 'prodofsize'
V =
2 2 4 2 6 2
>> prod(V)
ans = 384
>> size(allcomb(C{:}),1)
ans = 384
We take the combinations because their order is irrelevant.
More Answers (1)
Walter Roberson
on 22 Aug 2018
a = {'(1,3),'
'(5,4),'
'(9,7),(6,8),'
'(7,3),'
'(7,9),(2,4),(3,10),'
'(5,8)' };
nums = cellfun(@str2double, regexp(a, '\d+', 'match'), 'uniform', 0);
nums will now be a cell array of numeric row vectors.
Finding the minimal set would come after that. I think perhaps you might be able to use the sorts of techniques used to find a covering set
For example if you were to take nums and form the matrix
M = [
1 0 1 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 1 1 1 1 0
0 0 1 0 0 0 1 0 0 0
0 1 1 1 0 0 1 0 1 1
0 0 0 0 1 0 0 1 0 0
]
then the question would be to find the binary x with the lowest sum such that M * x' >= 1 for each row
This could probably be found with integer programming.
16 Comments
Walter Roberson
on 23 Aug 2018
+----------------------------------------+
| |
(1)------------------------[1, 2] |---[1,3]
| |
---(2)-------------------------+ +--[2, 3] |
| | | | |
| |---------------------------------+ | |
| | |
| (3)------------------------------------+ |
| | |
| +--------------------------------------------+
+----------------------------------------------------[2,4]
|
(4)-----------------------------------------------+
and so on.
Each node in your table gets connected to each of the nodes in the list of numbers for that node.
Now run the Vertex Cover algorithm. Or the Edge Cover algorithm, whichever turns out to be more appropriate.
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!