I am trying to solve the following problem:
- I have several blocked sets (which may contain duplicate elements).
- I must pick a (varying) number of elements from each blocked set to unblock it.
- I am only allowed to pick elements that also occur in the picking set.
- Whenever I remove an element from a blocked set I must also remove it from the picking set.
- The picking set may contain more or less elements than strictly required.
Minimal example:
//Syntax for blocking sets:
//Name (number of elements required to pick): {elements in set}
//Syntax for picking set:
//Name: {elements in set}
BS1 (1): {0, 1}
BS2 (1): {1, 2}
Picking Set: {1, 2}
Possible solution:
BS1 (1): {0, 1} <- take 1
BS2 (1): {1, 2} <- take 2
Picking Set: {1, 2} <- remove 1, 2
If picking 1 from BS2, the problem becomes unsolvable. The picking set will reduce to {2} and BS1 only contains {0, 1}, making further picks impossible.
A more difficult scenario:
BS1 (1): {1, 2, 4}
BS2 (2): {2, 3, 4}
BS3 (3): {1, 3, 4, 4}
Picking Set: {1, 2, 3, 4, 4, 4}
Possible Solution:
BS1 (1): {1, 2, 4} <- take 1
BS2 (2): {2, 3, 4} <- take 2, 4
BS3 (3): {1, 3, 4, 4} <- take 3, 4, 4
Picking Set: {1, 2, 3, 4, 4, 4} <- remove all
This scenario is solvable in multiple ways, but certain picks will lead to a dead end:
BS1 (1): {1, 2, 4} <- take 1
BS2 (2): {2, 3, 4} <- take 2, 3
BS3 (3): {1, 3, 4, 4} <- take 4, 4, and then dead end
Picking Set: {1, 2, 3, 4, 4, 4} <- remove all but one 4
My solution:
I wrote a recursive brute force algorithm that tests all picking combinations, then all following combinations of the next set based on that, etc. It works, but is slow. Number of combinations explodes but roughly half of the branches are successful, even for large problem instances. This makes me hopeful a heuristic or other method exists which can construct a valid solution directly.
My questions:
- Is there a name for this problem?
- What is the fastest way to construct a valid solution?
- Can we do better than brute force (generate guaranteed valid solutions without trial and error)?