8
1
Task
Given a Boolean matrix, find one (or optionally more) subset(s) of rows which have exactly one True in each column. You may use any algorithm, but must support very large matrices, like the last example.
One possible algorithm (Knuth's Algorithm X)
While there is no requirement to use this algorithm, it may be your best option.
- If the matrix A has no columns, the current partial solution is a valid solution; terminate successfully.
- Otherwise choose a column c.
- Choose* a row r such that Ar, c = 1.
- Include row r in the partial solution.
- For each column j such that Ar, j = 1,
for each row i such that Ai, j = 1,
delete row i from matrix A.
delete column j from matrix A. - Repeat this algorithm recursively on the reduced matrix A.
* Step 3 is non-deterministic, and needs to be backtracked to in the case of a failure to find a row in a later invocation of step 3.
Input
Any desired representation of the minimum 2×2 matrix A, e.g. as a numeric or Boolean array
1 0 0 1 0 0 1
1 0 0 1 0 0 0
0 0 0 1 1 0 1
0 0 1 0 1 1 0
0 1 1 0 0 1 1
0 1 0 0 0 0 1
or as Universe + Set collection
U = {1, 2, 3, 4, 5, 6, 7}
S = {
A = [1, 4, 7],
B = [1, 4],
C = [4, 5, 7],
D = [3, 5, 6],
E = [2, 3, 6, 7],
F = [2, 7]
}
or as 0 or 1 indexed sets;
{{1, 4, 7}, {1, 4}, {4, 5, 7}, {3, 5, 6}, {2, 3, 6, 7}, {2, 7}}
.
Output
Any desired representation of one (or optionally more/all) of the solutions, e.g. as numeric or Boolean array of the selected rows
1 0 0 1 0 0 0
0 0 1 0 1 1 0
0 1 0 0 0 0 1
or as Boolean list indicating selected rows {0, 1, 0, 1, 0, 1}
or as numeric (0 or 1 indexed) list of selected rows {2, 4, 6}
or as list of set names ['B', 'D', 'F']
.
More examples
In:
1 0 1
0 1 1
0 1 0
1 1 1
Out: 1 3
or 4
or 1 0 1 0
or 0 0 0 1
or [[1,3],[4]
etc.
In:
1 0 1 0 1
0 1 0 1 0
1 1 0 0 1
0 1 0 1 1
Out: 1 1 0 0
etc.
In:
0 1 0 1 1 0 1
1 1 0 0 1 1 1
0 1 0 0 1 0 0
1 1 1 0 0 0 1
0 0 0 1 1 1 0
Out: 0 0 0 1 1
etc.
In:
0 1 1
1 1 0
Out: Nothing or error or faulty solution, i.e. you do not have to handle inputs with no solution.
In: http://pastebin.com/raw/3GAup0fr
Out: 0 10 18 28 32 38 48 61 62 63 68 86 90 97 103 114 120 136 148 157 162 174 177 185 186 194 209 210 218 221 228 243 252 255 263 270 271 272 273 280 291 294 295 309 310 320 323 327 339 345 350 353 355 367 372 373 375 377 382 385 386 389 397 411 417 418 431 433 441 451 457 458 459 466 473 479 488 491 498 514 517
In: https://gist.github.com/angs/e24ac11a7d7c63d267a2279d416bc694
Out: 553 2162 2710 5460 7027 9534 10901 12281 12855 13590 14489 16883 19026 19592 19834 22578 25565 27230 28356 29148 29708 30818 31044 34016 34604 36806 36918 39178 43329 43562 45246 46307 47128 47906 48792 50615 51709 53911 55523 57423 59915 61293 62087 62956 64322 65094 65419 68076 70212 70845 71384 74615 76508 78688 79469 80067 81954 82255 84412 85227
You need to point out that step 3 is nondeterministic, and needs to be backtracked do in the case of a failure to find a row in a later invocation of step 3. Without that, the algorithm won't reliably work. – None – 2016-11-24T11:05:03.227
If we could go through every single one of the algorithms from Knuth's books, one by one, that would make an awesome collection! – None – 2016-11-24T11:43:46.117
@LuisMendo Done. – Adám – 2016-11-24T13:10:43.323
Isn't your first test case wrong? Shouldn't it be
{2, 4, 6}
if returned as row indices? – Billywob – 2016-11-24T13:11:35.343@Billywob Yes, typo. Thanks. – Adám – 2016-11-24T13:12:24.680
Can we assume that there are at least two rows of the matrix? – Billywob – 2016-11-24T13:33:15.180
@Billywob Yes, added. – Adám – 2016-11-24T13:41:56.927
4"Only solutions using this algorithm are eligible to win" but what exactly counts as "this algorithm"? How literally is it necessary to take "delete row" and "delete column"? And does the algorithm have to use the heuristic which is an key part of Knuth's presentation of the algorithm but which isn't mentioned at all in your description? – Peter Taylor – 2016-11-24T14:38:06.933
6It might be better to make a question which only asks for exact set cover but which has some hefty test cases which can't be handled by naïve brute force but can be handled by Knuth's algorithm. – Peter Taylor – 2016-11-24T14:40:26.130
1Relevant to Peter's comments. – Martin Ender – 2016-11-24T15:05:46.647
@PeterTaylor Very good point. If you edit in one or more such test cases, I will change the rules. – Adám – 2016-11-24T16:52:55.300
An actual Sudoku is too big to fit in the post: http://pastebin.com/raw/3GAup0fr
– Peter Taylor – 2016-11-24T23:21:49.180@PeterTaylor Added. Thank you. – Adám – 2016-11-25T12:52:38.203
1All algorithms are now equally allowed. – Adám – 2016-11-25T13:05:57.390
1"must support very large matrices" is quite ambiguous, especially since Knuth's algorithm can't handle the large test case without the column selection heuristic. Maybe have this question as pure [tag:code-golf] and have another as [tag:fastest-code]? – Angs – 2016-11-25T15:36:23.930
Here's an even larger problem in case anyone's interested – pentomino cover presented as an exact cover problem. – Angs – 2016-11-26T08:07:11.347
@Angs Thanks. Added. Run less than 5 seconds on my old slow laptop. – Adám – 2016-11-27T07:26:06.840