[Coin-osi-devel] OSI name support / disconnect with underlying OsiXXX

Lou Hafer lou at cs.sfu.ca
Thu Feb 15 23:46:56 EST 2007


	I'm mulling over a problem with a potential disconnect between names
held in the base OSI and names held in solvers. Here's a trivial example to
illustrate the problem using rows:

	Suppose I use addRow to create a constraint. addRow is pure virtual, so
each OsiXXX has its own implementation. The underlying solver may well have its
own notion of naming, and the OsiXXX will likely invent some name, or allow the
underlying solver to invent a name. At the least, a name will be needed in
order to implement writeMps (another pure virtual function). There's no
particular reason to assume that the solver's naming convention matches the
default name convention adopted in the base OSI class. And the addRow routine
will have no idea that the user may use setRowName to attach their own name to
the row.

	At this point, I have two names: one held in the OSI base, one held in
the OsiXXX implementation. This is not good. If the user looks at the file
generated by writeMps, it'll show a different name for the constraint than the
one the use has provided. I can reach this point with many different scenarios.

	Another aspect of the problem is an efficiency issue. It's wasteful to
have the OsiXXX::addRow routine generate a name, only to have it immediately
overwritten by a name supplied by the user.

	Another aspect of the problem is that we don't want to break existing
code. Nor do we want to force users to call addRow, then setRowName. A single
call to addRow(<row info>,name) would be better.

	One approach would be to throw the problem back on the OsiXXX
maintainers. Declare a pure virtual addRow(<row info>,name) and require that
each OsiXXX implement it. This would be a huge disruption. A less disruptive
(but more deceptive) approach would be to declare an impure virtual function

OSI::addRow(<row info>, name)
{ OsiXXX::addRow(<row info>) ;
  OSI::setRowName(name) ; }

In other words, unless the OsiXXX maintainer overrides the default, the name
is simply not propagated into the OsiXXX implementation. No existing code
breaks, and names will always be available, but it's possible for names to get
out of sync between the OSI base and the OsiXXX implementation. If the OsiXXX
maintainer decides to override, the routine would look like this:

OsiXXX::addRow (<row info>, name)
{ << do whatever is needed to add the constraint, with the name >>
  OSI::setRowName(name) ; }

where the call to setRowName propagates the info back up to the base OSI
object. Similarly, OsiXXX::addRow(<row info>) could be augmented as

OsiXXX::addRow(<row info>)
{ name = OSI::dfltRowColName(...) ;
  << do whatever is needed to add the constraint, with the name >> }

	So far, the `less disruptive but deceptive' approach is the best that's
occurred to me.  For many cases, where the base constraint system is read in
from an MPS file, CoinModel, or similar, and the user only cares about the
solution in terms of the original constraints and variables, the disconnect
might never be visible.  OsiXXX maintainers could upgrade at their leisure, and
always have the option of overriding the base class methods and pulling name
support entirely within the OsiXXX class.

	Opinions and suggestions, please.


More information about the Osi mailing list