[Coin-discuss] Hints, throws, OsiForceDo
Lou Hafer
lou at cs.sfu.ca
Wed May 7 15:05:11 EDT 2003
Folks,
After working up an initial implementation of hints for
OsiDylpSolverInterface (ODSI), I did a rewrite of testHintParam in the
unitTest so that it would check for proper use of throws when the strength is
OsiForceDo. The results were, in hindsight, obvious: A throw for every hint,
true or false, when strength is OsiForceDo. The result is the same for dylp
and for clp (my default testing partner).
Arguably the client should be expecting the possibility of a throw
when using OsiForceDo, but it seems like a `throw on failure' policy would be
more appropriate.
The OsiSolverInterface (OSI) hint arrays are private data, so there's
no way to reach them except through the default [set,get]HintParam routines.
Possible solutions:
0) Do nothing. Client must always be prepared to catch, then ascertain
success/failure.
1) Declare the hint arrays protected, so they could be accessed directly
by derived classes. [set,get]HintParam are simply overridden.
2) Catch the throw in the getHintParam method of the derived class. Rethrow
if appropriate.
3) Abandon the hint arrays declared in OSI and declare new hint arrays in
the derived class.
Currently I've implemented 2). I'd actually prefer 1), from an `ease of use'
viewpoint, but it allows exposure of OSI implementation details.
Revised testHintParam code follows, with informational printing.
Thoughts?
Lou
=======================================================================
#include <sstream>
static bool testHintParam(OsiSolverInterface * si, int k, bool sense,
OsiHintStrength strength)
/*
Tests for proper behaviour of [set,get]HintParam methods. The initial get
tests if the hint is implemented.
If yes, a pair of set/get calls is performed at the strength specified by
the parameter. This can return true or (at strength OsiForceDo) throw an
exception. The rationale would be that only OsiForceDo must be obeyed, so
anything else should return true regardless of whether the solver followed
the hint.
If no, attempting to set the hint should return false or throw an exception
at strength OsiForceDo.
*/
{ bool post_sense = true, pre_sense = true ;
OsiHintStrength post_strength = OsiHintDo, pre_strength = OsiHintDo ;
bool ret ;
OsiHintParam key = static_cast<OsiHintParam>(k) ;
if (si->getHintParam(key,pre_sense,pre_strength))
{ ret = false ;
try
{ if (si->setHintParam(key,sense,strength))
{ ret = (si->getHintParam(key,post_sense,post_strength) == true) &&
(post_strength == strength) ; } }
catch (CoinError)
{ std::ostringstream msg ;
msg << "setHintParam throw for hint " << key << " sense " << sense <<
" strength " << strength ;
failureMessage(*si,msg.str()) ;
ret = (strength == OsiForceDo) ; } }
else
{ ret = true ;
try
{ ret = si->setHintParam(key,sense,strength) ; }
catch (CoinError)
{ std::ostringstream msg ;
msg << "setHintParam throw for hint " << key << " sense " << sense <<
" strength " << strength ;
failureMessage(*si,msg.str()) ;
ret = !(strength == OsiForceDo) ; } }
return ret ; }
// And add these two lines with all the other calls to testHintParam
assert(!exists ^ testHintParam(si, i, true, OsiForceDo));
assert(!exists ^ testHintParam(si, i, false, OsiForceDo));
More information about the Coin-discuss
mailing list