[Coin-discuss] re: Preserving row and column names using readLP & OsiSolverInterface

John J Forrest jjforre at us.ibm.com
Thu Feb 2 12:25:17 EST 2006


Francois,

I strongly disagree.  If there are no names or no duplicates then the code 
I added is not invoked.  If there are duplicates then without my change 
accessing some row names will give a segmentation error.  The hash 
functions are never used for row names and it is only row names I am 
checking.

So I think my solution does not harm anyone and helps people who have 
duplicates.

John Forrest



Francois Margot <fmargot at andrew.cmu.edu> 
Sent by: coin-discuss-bounces at list.coin-or.org
02/02/2006 12:03 PM
Please respond to
Discussions about open source software for Operations Research 
<coin-discuss at list.coin-or.org>


To
Discussions about open source software for Operations Research 
<coin-discuss at list.coin-or.org>
cc

Subject
Re: [Coin-discuss] re: Preserving row and column names using readLP     & 
OsiSolverInterface








Looking at the diff:

+    if(numberHash_[0] != numberRows_) {
+      printf("### WARNING: CoinLpIO::setLpDataRowAndColNames(): non 
distinct row names\n");
+      // We don't normally use row names as hash so put back
+      stopHash(0);
+      names_[0] = (char **) malloc(numberRows_ * sizeof(char *));
+      char ** names = names_[0];
+      for (int i=0;i<numberRows_;i++)
+      names[i]=strdup(rownames[i]);
+    }

startHash(0) is doing more than just setting up the vector "names". 
Calling 
stopHash(0) deletes allocated memory and resets constants maxHash_[0]
and  numberHash_[0] to 0. I am afraid that this code creates bugs.

I don't understand why you have to modify CoinLpIO to make OsiClp pass
untiTest. Why not modify your unitTest? If you read an LP file with 
distinct
row names (or without row names, i.e. calling 
CoinLpIO::setLpDataRowAndColNames() with a NULL vector for the row names) 
there should be no problems.

Francois


On Wed, 1 Feb 2006, John J Forrest wrote:

> James,
>
> OsiClpSolverInterface::readLp and writeLp in cvs.  I had to make some
> changes to CoinLpIO when there are duplicate row names from ranges -
> otherwise it fails unitTest.
>
> John Forrest
>
>
>
> "James Gibbons" <James.Gibbons at nottingham.ac.uk>
> Sent by: coin-discuss-bounces at list.coin-or.org
> 02/01/2006 09:27 AM
> Please respond to
> Discussions about open source software for Operations Research
> <coin-discuss at list.coin-or.org>
>
>
> To
> <coin-discuss at list.coin-or.org>
> cc
>
> Subject
> [Coin-discuss] re: Preserving row and column names using readLP &
> OsiSolverInterface
>
>
>
>
>
>
> Dear All,
>
> Replying to myself about previous message (text at end). Investigating
> further I don't think the OsiSolverInterface::readLp function, inherited
> by OsiClpSolverInterface copies the neames into the Solver object. I've
> fixed this problem for me locally by adding the following  function to
> OsiClpSolverInterface.cpp (and a corresponding declaration in
> OsiClpSolverInterface.hpp). the function is adapted from
> OsiSolverInterface::readLp and OsiClpSolverInterface::readMps. I guess
> there maybe a more elegant way of doing this as the message handler 
stuff
> doesn't work and CoinLpIO::readLp doesn't return the number of errors. 
Is
> there any chane of getting this or an improved version included in the
> code base?
>
> Thanks,
>
> James
>
> int
> OsiClpSolverInterface::readLp(const char * filename, const double 
epsilon)
> {
>
>  // Get rid of integer stuff
>  delete [] integerInformation_;
>  integerInformation_=NULL;
>
>  CoinLpIO m;
>  m.setInfinity(getInfinity());
>  //m.passInMessageHandler(modelPtr_->messageHandler());
>  //*m.messagesPointer()=modelPtr_->coinMessages();
>
>  //handler_->message(COIN_SOLVER_MPS,messages_)
>  //  <<m.getProblemName()<< numberErrors <<CoinMessageEol;
>  int numberErrors = 0;
>  m.readLp(filename, epsilon);
>
>  if (!numberErrors) {
>                   // set objective function offest
>                   setDblParam(OsiObjOffset, 0);
>
>                   // set problem name
>                   setStrParam(OsiProbName, m.getProblemName());
>
>                   // no errors
> loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),
> m.getObjCoefficients(),m.getRowSense(),m.getRightHandSide(),
>                                 m.getRowRange());
>
>                   const char *integer = m.integerColumns();
>                   int nCols = m.getNumCols();
>                   int nRows = m.getNumRows();
>                   if (integer) {
>                                 int i, n = 0;
>                                 int *index = new int [nCols];
>                                 for (i=0; i<nCols; i++) {
>                                   if (integer[i]) {
>                                 index[n++] = i;
>                                   }
>                                 }
>                                 setInteger(index,n);
>                                 delete [] index;
>                   }
>
>                   // Always keep names
>                   int iRow;
>      std::vector<std::string> rowNames = std::vector<std::string> ();
>      std::vector<std::string> columnNames = std::vector<std::string> ();
>      rowNames.reserve(nRows);
>      for (iRow=0;iRow<nRows;iRow++) {
>                                 const char * name = m.rowName(iRow);
>                                 rowNames.push_back(name);
>                   }
>
>      int iColumn;
>      columnNames.reserve(nCols);
>      for (iColumn=0;iColumn<nCols;iColumn++) {
>                                 const char * name =
> m.columnName(iColumn);
>                                 columnNames.push_back(name);
>      }
>      modelPtr_->copyNames(rowNames,columnNames);
>  }
>  return numberErrors;
>
> Dear all,
>
> I am trying to use the Clp and Cbc solvers to solve a problem generated 
by
> XpressMP Mosel. I have been able to read and solve the problem as a .lp
> file but not using a .mps file. (I think Xpress mps files might have a
> non-standard extension to the format?).
>
> What I can't work out how to do is too keep the row and column names 
from
> the original problem. A simple example:
>
>    OsiClpSolverInterface solver0;
>    std::string fn = "test2.lp";
>    solver0.readLp(fn.c_str());
>    int ncols = solver0.getNumCols();
>    for(int i=0;i<ncols;i++) {
>                                 std::cout<<solver0.getColName(i)<<"\n";}
>
> This outputs the column names as C0000001 etc. As there is no guarantee
> about what order Mosel generates the matrix in I really need access to 
the
> names. I've tried recompiling with LPIO_DEBUG defined in the 
CoinLPIO.cpp
> file and the output from this suggests that readLp is reading in the
> problem names correctly. So am I missing something obvious or doing
> something wrong?
>
> Thanks,
>
> James
>
> This message has been checked for viruses but the contents of an
> attachment
> may still contain software viruses, which could damage your computer
> system:
> you are advised to perform your own checks. Email communications with 
the
> University of Nottingham may be monitored as permitted by UK 
legislation.
>
>
> _______________________________________________
> Coin-discuss mailing list
> Coin-discuss at list.coin-or.org
> http://list.coin-or.org/mailman/listinfo/coin-discuss
>
>
_______________________________________________
Coin-discuss mailing list
Coin-discuss at list.coin-or.org
http://list.coin-or.org/mailman/listinfo/coin-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/coin-discuss/attachments/20060202/4669dbd5/attachment.html>


More information about the Coin-discuss mailing list