Using duality to solve discrete optimization problems: Theory and computational experience