[Coin-discuss] Matthieu.Bolt at klm.com

MMHJ Bolt mmhjbolt at hotmail.com
Wed Nov 8 10:33:01 EST 2006


Hi all,

I used CbcMain.cpp as an example for constructing my own solver.
All compiled fine but I don't understand the methods preProcess and 
postProcess from the class CglPreProcess:

OsiSolverInterface * preProcess( OsiSolverInterface & model, bool 
makeEquality=false, int numberPasses=5)
void postProcess(OsiSolverInterface &model);

More specific I have the following questions:

- Should preProcess be called before or after adding cut generators to the 
model?

- Why is the first parameter of preProcess called "model" while it is a 
solver?
I find this confusing because at the moment I call preProcess I have already 
assigned a solver to my CbcModel.

- What happens with the first parameter in the method preProcess?
Given that the reference isn't const I think that the passed solver will be 
altered by preProcess.
More evidence for this idea comes from CbcMain.cpp where the passed solver 
is a fresh clone from the solver assigned to the CbcModel (lines 1191 and 
1194).

1188	OsiSolverInterface * saveSolver=NULL;
1189	CglPreProcess process;
1190	if(preProcess) {
1191	saveSolver=model->solver()->clone();
1192	/* Do not try and produce equality cliques and
1193	   do up to 10 passes */
1194	OsiSolverInterface * solver2 = 
process.preProcess(*saveSolver,false,10);
1195	if (!solver2) {
1196		printf("Pre-processing says infeasible\n");
1197		break;
1198	} else {
1199		printf("processed model has %d rows and %d columns\n",
1200			solver2->getNumRows(),solver2->getNumCols());
1201	}
1202	//solver2->resolve();
1203	// we have to keep solver2 so pass clone
1204	solver2 = solver2->clone();
1205	model->assignSolver(solver2);
1206	model->initialSolve();
1207	}

But if this is the case then why not simply pas a reference to the solver 
used in the CbcModel since at line 1205 the model will be assigned a new 
OsiSolverInterface and meanwhile isn't used?
Perhaps the passed solver is a clone from the solver assigned to the 
CbcModel because this CbcModel is assigned the preprocessed solver at line 
1205 and saveSolver is used later on?

-What is the parameter in the method postProcess (again called model instead 
of solver)?
Is this the original solver, the preprocessed solver, the postpressed 
soolver or something else?
In CbcMain.ccp the solver assigned to the CbcModel is passed but this is 
secretly a clone of the preprocessed solver (line 1204/1205).
But then saveSolver is again assigned to the model.
This solver might be altered by preProcess.

1303	if (preProcess) {
1304		process.postProcess(*model->solver());
1305		// Solution now back in saveSolver
1306		model->assignSolver(saveSolver);
1307	}

-Who is responsible for deleting the cloned solvers?


Well anyways I wrote my preProcessing code according to CbcMain.cpp and 
added it after adding cut generators to the model.

CglPreProcess process	;
OsiSolverInterface * saveSolver	;
if( preProcess ) {
	// Clone the model because column names might be lost otherwise
	saveSolver = model.solver( )->clone( )	;

	// Remove weaker constraints by preprocessing, presolve
	OsiSolverInterface * tempSolver = process.preProcess( *saveSolver, false, 
10 )	;

	// Check if the problem is still feasible
	if( !tempSolver ) {
		return -1	;
	}
	tempSolver = tempSolver->clone( )	;
	model.assignSolver( tempSolver )	;
}

if( preProcess ) {
	process.postProcess( *model.solver( ) )	;

	// Solution now back in orignal model
	model.assignSolver( saveSolver )	;
}

And this works because a solution for my problem is found.
However if I print the solution to an output file with the column names it 
seems that some variables are not matched with the right column names.
The values seem to have shifted the number of colums removed from the 
original problem by preprocessing.
Because this problem could also be caused by this printing I give the 
related code but I don't think the problem is located there.

// Reread the MPS file for the column names
CoinMpsIO mpsInfo	;
mpsInfo.readMps( input.GetFullName( ).mb_str( ), "" )	;

// Create the specified output file
wxTextFile output( outputFileName.GetFullName( ) )	;

//Write the solution value
wxString solValue;
solValue.Printf( _T( "VALUE\t%g\n" ), model.getObjValue( ) )	;
output.AddLine( solValue )	;

// For all columns in the model
for( int iColumn = 0 ; iColumn < numberColumns ; ++iColumn )
{
	// Write the name of the variable of the current column and it's value on 
one line
	wxString line	;
	wxString columnName( mpsInfo.columnName( iColumn ), wxConvUTF8 )	;
	if( fabs( solution[ iColumn ] ) > 1.0e-7 )
	{
		line.Printf( _T( "%s %g%c" ), columnName, solution[ iColumn ]  )	;
	}
	else
	{
		line.Printf( _T( "%s %d\n" ), columnName, 0 )	;
	}
	output.AddLine( line )	;
}
output.Write( )	;
output.Close( )	;

I tried to provide all the informations I know, I hope it's enough for 
someone to help me since I'm stuck. Thanks in advance for any information 
and help.

MMHJ Bolt

_________________________________________________________________
Windows Live Messenger: gratis bellen van PC naar PC 
http://imagine-msn.com/messenger/launch80/default.aspx?locale=nl-nl




More information about the Coin-discuss mailing list