------ art_21188_20244148.1212960079726
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
I have a solution at the end of this message. This solution finds the
optimal solution. I believe this problem is NP-complete, so a fast optimal
solution for large inputs is out of the question. But, there are some
things that I did that give significant performance improvement:
* Used memoization to not recalculate costs for subsets that have already
been computed. This reduced the complexity from O(n!) to O(2**n).
* Divided finding the pairs into 2 phases: finding min cost, and finding
pairs based on min costs. This simplified the bottleneck of finding the min
cost and reduced its overhead. Given the min costs, the pairs can be found
in O(n**2).
* Mapped each player to a bit index/mask. This allowed a set of players to
be represented as simply an Integer/Fixnum.
* Applied some O(1) bit-searching techniques I developed about 10 years ago
on the hardware side (x86 BSR - bit-scan-reverse).
* No small objects are created (and garbage collected) during the algorithm.
Eric
#!/usr/bin/env ruby
Infinity .0/0.0
class PreferrablePairs
def initialize
# remaining bit pattern cost (init to no remaining 0)
# size will be O(2**n)
# only patterns with an even number of bits set will be used
@cost 0]
#@cost 0 } # Hash could be used just as well (little slower)
@mask # next mask to use
# mask <