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

James Gibbons James.Gibbons at nottingham.ac.uk
Wed Feb 1 09:27:51 EST 2006


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.





More information about the Coin-discuss mailing list