I previously wrote about the Bay Bridges Challenge, hosted at CodeEval. In my last post, I showed that the problem could be modeled as a minimum vertex cover problem, and wondered if we can do better than iterating through the power set of bridges, and picking the highest cardinality subset that is feasible. I said that most likely,
there is additional structure inherent in the problem, that can be exploited to make the problem more tractable.
Spurred by some helpful recent comments, I spent some more time on the problem. As it turns out, we can do better than an exhaustive search. But first, remember that a feasible solution is any set of bridges with no intersections. Our task is to find an optimal solution, which is simply the largest such feasible solution (note that there can be more than one).
Claim 1: If there is no feasible solution with bridges, then there cannot be a larger feasible solution.
Proof (by contradiction): Assume that there is a solution with bridges. The removal of any bridge from this solution should still be a set of non-intersecting bridges, i.e., a feasible solution, but of size , which is a contradiction. By induction, we can see that this is also true for higher values of . QED.
With this claim in hand, let us partition the power set of bridges so that represents the set of all sets of bridges of length . We can then make the following observation about the partitions (we can safely ignore the empty partition ):
If any set in is feasible, the optimal solution is in one of the partitions through . Otherwise, it is in one of the partitions through .
In other words, we can do a binary search on the partition index until we find the partition with the optimal solution. While this seems very promising, the partition size unfortunately has a maximum at (note that ). So, in the worst case, we still need to search an exponential number of bridge sets.d But in practice, this should still be significantly better than exhaustively searching each partition.
Anyway, I didn’t really feel like coding up this binary search, so I tried submitting a simpler, more naive solution: Search each partition , starting with , in decreasing order of , until you find the first feasible solution , and return . Because of Claim 1, it is easy to see that will be an optimal solution to our problem. It turns out that this approach was enough to get a score of 100 (with a ranking of 86). So, now I am even less inclined to implement binary search.
Also, I should really post the code for all of my solutions to github, which I hope to do soon.