<br><font size=2 face="sans-serif">Francois,</font>
<br>
<br><font size=2 face="sans-serif">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.</font>
<br>
<br><font size=2 face="sans-serif">So I think my solution does not harm
anyone and helps people who have duplicates.</font>
<br>
<br><font size=2 face="sans-serif">John Forrest</font>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td width=40%><font size=1 face="sans-serif"><b>Francois Margot <fmargot@andrew.cmu.edu></b>
</font>
<br><font size=1 face="sans-serif">Sent by: coin-discuss-bounces@list.coin-or.org</font>
<p><font size=1 face="sans-serif">02/02/2006 12:03 PM</font>
<table border>
<tr valign=top>
<td bgcolor=white>
<div align=center><font size=1 face="sans-serif">Please respond to<br>
Discussions about open source software for Operations Research    
   <coin-discuss@list.coin-or.org></font></div></table>
<br>
<td width=59%>
<table width=100%>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">To</font></div>
<td><font size=1 face="sans-serif">Discussions about open source software
for Operations Research <coin-discuss@list.coin-or.org></font>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">cc</font></div>
<td>
<tr valign=top>
<td>
<div align=right><font size=1 face="sans-serif">Subject</font></div>
<td><font size=1 face="sans-serif">Re: [Coin-discuss] re: Preserving row
and column names using readLP        &
       OsiSolverInterface</font></table>
<br>
<table>
<tr valign=top>
<td>
<td></table>
<br></table>
<br>
<br>
<br><tt><font size=2><br>
<br>
Looking at the diff:<br>
<br>
+    if(numberHash_[0] != numberRows_) {<br>
+      printf("### WARNING: CoinLpIO::setLpDataRowAndColNames():
non distinct row names\n");<br>
+      // We don't normally use row names as hash so put
back<br>
+      stopHash(0);<br>
+      names_[0] = (char **) malloc(numberRows_ * sizeof(char
*));<br>
+      char ** names = names_[0];<br>
+      for (int i=0;i<numberRows_;i++)<br>
+      names[i]=strdup(rownames[i]);<br>
+    }<br>
<br>
startHash(0) is doing more than just setting up the vector "names".
Calling <br>
stopHash(0) deletes allocated memory and resets constants maxHash_[0]<br>
and  numberHash_[0] to 0. I am afraid that this code creates bugs.<br>
<br>
I don't understand why you have to modify CoinLpIO to make OsiClp pass<br>
untiTest. Why not modify your unitTest? If you read an LP file with distinct<br>
row names (or without row names, i.e. calling <br>
CoinLpIO::setLpDataRowAndColNames() with a NULL vector for the row names)
<br>
there should be no problems.<br>
<br>
Francois<br>
<br>
<br>
On Wed, 1 Feb 2006, John J Forrest wrote:<br>
<br>
> James,<br>
><br>
> OsiClpSolverInterface::readLp and writeLp in cvs.  I had to make
some<br>
> changes to CoinLpIO when there are duplicate row names from ranges
-<br>
> otherwise it fails unitTest.<br>
><br>
> John Forrest<br>
><br>
><br>
><br>
> "James Gibbons" <James.Gibbons@nottingham.ac.uk><br>
> Sent by: coin-discuss-bounces@list.coin-or.org<br>
> 02/01/2006 09:27 AM<br>
> Please respond to<br>
> Discussions about open source software for Operations Research<br>
> <coin-discuss@list.coin-or.org><br>
><br>
><br>
> To<br>
> <coin-discuss@list.coin-or.org><br>
> cc<br>
><br>
> Subject<br>
> [Coin-discuss] re: Preserving row and column names using readLP &<br>
> OsiSolverInterface<br>
><br>
><br>
><br>
><br>
><br>
><br>
> Dear All,<br>
><br>
> Replying to myself about previous message (text at end). Investigating<br>
> further I don't think the OsiSolverInterface::readLp function, inherited<br>
> by OsiClpSolverInterface copies the neames into the Solver object.
I've<br>
> fixed this problem for me locally by adding the following  function
to<br>
> OsiClpSolverInterface.cpp (and a corresponding declaration in<br>
> OsiClpSolverInterface.hpp). the function is adapted from<br>
> OsiSolverInterface::readLp and OsiClpSolverInterface::readMps. I guess<br>
> there maybe a more elegant way of doing this as the message handler
stuff<br>
> doesn't work and CoinLpIO::readLp doesn't return the number of errors.
Is<br>
> there any chane of getting this or an improved version included in
the<br>
> code base?<br>
><br>
> Thanks,<br>
><br>
> James<br>
><br>
> int<br>
> OsiClpSolverInterface::readLp(const char * filename, const double
epsilon)<br>
> {<br>
><br>
>  // Get rid of integer stuff<br>
>  delete [] integerInformation_;<br>
>  integerInformation_=NULL;<br>
><br>
>  CoinLpIO m;<br>
>  m.setInfinity(getInfinity());<br>
>  //m.passInMessageHandler(modelPtr_->messageHandler());<br>
>  //*m.messagesPointer()=modelPtr_->coinMessages();<br>
><br>
>  //handler_->message(COIN_SOLVER_MPS,messages_)<br>
>  //  <<m.getProblemName()<< numberErrors <<CoinMessageEol;<br>
>  int numberErrors = 0;<br>
>  m.readLp(filename, epsilon);<br>
><br>
>  if (!numberErrors) {<br>
>                   //
set objective function offest<br>
>                   setDblParam(OsiObjOffset,
0);<br>
><br>
>                   //
set problem name<br>
>                   setStrParam(OsiProbName,
m.getProblemName());<br>
><br>
>                   //
no errors<br>
> loadProblem(*m.getMatrixByCol(),m.getColLower(),m.getColUpper(),<br>
> m.getObjCoefficients(),m.getRowSense(),m.getRightHandSide(),<br>
>                    
            m.getRowRange());<br>
><br>
>                   const
char *integer = m.integerColumns();<br>
>                   int
nCols = m.getNumCols();<br>
>                   int
nRows = m.getNumRows();<br>
>                   if
(integer) {<br>
>                    
            int i, n = 0;<br>
>                    
            int *index = new int [nCols];<br>
>                    
            for (i=0; i<nCols; i++) {<br>
>                    
              if (integer[i]) {<br>
>                    
            index[n++] = i;<br>
>                    
              }<br>
>                    
            }<br>
>                    
            setInteger(index,n);<br>
>                    
            delete [] index;<br>
>                   }<br>
><br>
>                   //
Always keep names<br>
>                   int
iRow;<br>
>      std::vector<std::string> rowNames = std::vector<std::string>
();<br>
>      std::vector<std::string> columnNames = std::vector<std::string>
();<br>
>      rowNames.reserve(nRows);<br>
>      for (iRow=0;iRow<nRows;iRow++) {<br>
>                    
            const char * name = m.rowName(iRow);<br>
>                    
            rowNames.push_back(name);<br>
>                   }<br>
><br>
>      int iColumn;<br>
>      columnNames.reserve(nCols);<br>
>      for (iColumn=0;iColumn<nCols;iColumn++) {<br>
>                    
            const char * name =<br>
> m.columnName(iColumn);<br>
>                    
            columnNames.push_back(name);<br>
>      }<br>
>      modelPtr_->copyNames(rowNames,columnNames);<br>
>  }<br>
>  return numberErrors;<br>
><br>
> Dear all,<br>
><br>
> I am trying to use the Clp and Cbc solvers to solve a problem generated
by<br>
> XpressMP Mosel. I have been able to read and solve the problem as
a .lp<br>
> file but not using a .mps file. (I think Xpress mps files might have
a<br>
> non-standard extension to the format?).<br>
><br>
> What I can't work out how to do is too keep the row and column names
from<br>
> the original problem. A simple example:<br>
><br>
>    OsiClpSolverInterface solver0;<br>
>    std::string fn = "test2.lp";<br>
>    solver0.readLp(fn.c_str());<br>
>    int ncols = solver0.getNumCols();<br>
>    for(int i=0;i<ncols;i++) {<br>
>                    
            std::cout<<solver0.getColName(i)<<"\n";}<br>
><br>
> This outputs the column names as C0000001 etc. As there is no guarantee<br>
> about what order Mosel generates the matrix in I really need access
to the<br>
> names. I've tried recompiling with LPIO_DEBUG defined in the CoinLPIO.cpp<br>
> file and the output from this suggests that readLp is reading in the<br>
> problem names correctly. So am I missing something obvious or doing<br>
> something wrong?<br>
><br>
> Thanks,<br>
><br>
> James<br>
><br>
> This message has been checked for viruses but the contents of an<br>
> attachment<br>
> may still contain software viruses, which could damage your computer<br>
> system:<br>
> you are advised to perform your own checks. Email communications with
the<br>
> University of Nottingham may be monitored as permitted by UK legislation.<br>
><br>
><br>
> _______________________________________________<br>
> Coin-discuss mailing list<br>
> Coin-discuss@list.coin-or.org<br>
> http://list.coin-or.org/mailman/listinfo/coin-discuss<br>
><br>
><br>
_______________________________________________<br>
Coin-discuss mailing list<br>
Coin-discuss@list.coin-or.org<br>
http://list.coin-or.org/mailman/listinfo/coin-discuss<br>
</font></tt>
<br>