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