Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to disable dual reductions for Clp #630

Merged
merged 5 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/Cbc_C_Interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ struct Cbc_Model {
// parameters
enum LPMethod lp_method;
enum DualPivot dualp;
enum LPReductions red_type = LPR_Default;

// lazy constraints
CglStored *lazyConstrs;
Expand Down Expand Up @@ -1763,7 +1764,7 @@ static void Cbc_addAllSOS( Cbc_Model *model, CbcModel &cbcModel );
static void Cbc_addMS( Cbc_Model *model, CbcModel &cbcModel );

int CBC_LINKAGE
Cbc_solveLinearProgram(Cbc_Model *model)
Cbc_solveLinearProgram(Cbc_Model *model)
{
Cbc_flush( model );
OsiClpSolverInterface *solver = model->solver_;
Expand Down Expand Up @@ -1909,6 +1910,10 @@ Cbc_solveLinearProgram(Cbc_Model *model)

/* for integer or linear optimization starting with LP relaxation */
ClpSolve clpOptions;
if (model->red_type == LPR_NoDualReds){
// set special option in Clp to disable dual reductions
clpOptions.setSpecialOption(5, 1);
}
char methodName[256] = "";
switch (model->lp_method) {
case LPM_Auto:
Expand Down Expand Up @@ -4745,6 +4750,21 @@ Cbc_setLPmethod(Cbc_Model *model, enum LPMethod lpm ) {
model->lp_method = lpm;
}

/** gets the dual reductions to be used when solving the LP
*/
double CBC_LINKAGE
Cbc_getDualReductionsType(Cbc_Model *model){
return model->red_type;
}

/** sets the dual reductions to be used when solving the LP
*/

void CBC_LINKAGE
Cbc_setDualReductionsType(Cbc_Model *model, enum LPReductions red) {
model->red_type = red;
}


void * CBC_LINKAGE
Cbc_getSolverPtr(Cbc_Model *model) {
Expand Down
36 changes: 28 additions & 8 deletions src/Cbc_C_Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ enum LPMethod {
LPM_BarrierNoCross = 4 /*! Barrier algorithm, not to be followed by crossover */
};

/*! Whether specific presolve reductions should be disabled
* */
enum LPReductions {
LPR_Default = 0, /*! Solver will use default presolve transformations */
LPR_NoDualReds = 1 /*! Dual reduction transformation will be disabled */
};

/*! Selects the pivot selection strategy to be used
* in the dual simplex algorithm.
* */
Expand Down Expand Up @@ -1079,6 +1086,18 @@ Cbc_setCutoff(Cbc_Model *model, double cutoff);
CBCLIB_EXPORT void CBC_LINKAGE
Cbc_setLPmethod(Cbc_Model *model, enum LPMethod lpm );

/**
* gets type of dual reductions to use when solving the LP
*/
CBCLIB_EXPORT double CBC_LINKAGE
Cbc_getDualReductionsType(Cbc_Model *model);

/**
* sets whether not to use dual reductions when solving the LP
*/
CBCLIB_EXPORT void CBC_LINKAGE
Cbc_setDualReductionsType(Cbc_Model *model, enum LPReductions red);

/** Returns a pointer to the OsiClpSolverInterface object
* containing the problem
*/
Expand Down Expand Up @@ -1153,18 +1172,19 @@ CBCLIB_EXPORT int CBC_LINKAGE
Cbc_solve(Cbc_Model *model);

/** @brief Solves only the linear programming relaxation
*
* @param model problem object
* @return execution status
* 0 optimal
* 1 incomplete search (stopped on time, iterations)
* 2 infeasible
* 3 unbounded
**/
*
* @param model problem object
* @return execution status
* 0 optimal
* 1 incomplete search (stopped on time, iterations)
* 2 infeasible
* 3 unbounded
**/
CBCLIB_EXPORT int CBC_LINKAGE
Cbc_solveLinearProgram(Cbc_Model *model);



/** @brief This is a pre-processing that tries to
* strengthen set packing constraints. Dominated constraints are
* removed. */
Expand Down
94 changes: 94 additions & 0 deletions test/CInterfaceTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,96 @@ void testTSPUlysses22( char lazy ) {
Cbc_deleteModel(m);
}

void testDualReductionsType( enum LPReductions red ){
Cbc_Model *model = Cbc_newModel();

/* Simple knapsack problem
Maximize 5x[1] + 3x[2] + 2x[3] + 7x[4] + 4x[5]
s.t. 2x[1] + 8x[2] + 4x[3] + 2x[4] + 5x[5] <= 10
All x binary
*/

CoinBigIndex start[] = {0, 1, 2, 3, 4, 5, 6};
int rowindex[] = {0, 0, 0, 0, 0};
double value[] = {2, 8, 4, 2, 5};
double collb[] = {0,0,0,0,0};
double colub[] = {1,1,1,1,1};
double obj[] = {5, 3, 2, 7, 4};
double feasible[] = {1,1,0,0,0};
double rowlb[] = {-INFINITY};
double rowub[] = {10};
const double *sol;
const char* setname = "test model";
char *getname = malloc(20);
int i;

printf("Interface reports Cbc version %s\n", Cbc_getVersion());

Cbc_loadProblem(model, 5, 1, start, rowindex, value, collb, colub, obj, rowlb, rowub);

Cbc_setColName(model, 2, "var2");
Cbc_setRowName(model, 0, "constr0");


assert(Cbc_getNumCols(model) == 5);
assert(Cbc_getNumRows(model) == 1);

for (i = 0; i < 5; i++) {
Cbc_setInteger(model, i);
assert(Cbc_isInteger(model,i));
}

Cbc_setObjSense(model, -1);
assert(Cbc_getObjSense(model) == -1);

Cbc_setProblemName(model, setname);

Cbc_registerCallBack(model, test_callback);

Cbc_setInitialSolution(model, feasible);

Cbc_setDualReductionsType(model, red);

assert(Cbc_getDualReductionsType(model) == red);

Cbc_solve(model);

assert(Cbc_isProvenOptimal(model));
assert(!Cbc_isAbandoned(model));
assert(!Cbc_isProvenInfeasible(model));
assert(!Cbc_isContinuousUnbounded(model));
assert(!Cbc_isNodeLimitReached(model));
assert(!Cbc_isSecondsLimitReached(model));
assert(!Cbc_isSolutionLimitReached(model));
assert(fabs(Cbc_getObjValue(model)- (16.0)) < 1e-6);
assert(fabs(Cbc_getBestPossibleObjValue(model)- 16.0) < 1e-6);

assert(callback_called == 1);

sol = Cbc_getColSolution(model);

assert(fabs(sol[0] - 1.0) < 1e-6);
assert(fabs(sol[1] - 0.0) < 1e-6);
assert(fabs(sol[2] - 0.0) < 1e-6);
assert(fabs(sol[3] - 1.0) < 1e-6);
assert(fabs(sol[4] - 1.0) < 1e-6);

Cbc_problemName(model, 20, getname);
i = strcmp(getname,setname);
assert( (i == 0) );

Cbc_getColName(model, 2, getname, 20);
i = strcmp(getname, "var2");
assert( (i == 0) );
Cbc_getRowName(model, 0, getname, 20);
i = strcmp(getname, "constr0");
assert( (i == 0) );
assert( Cbc_maxNameLength(model) >= 7 );

Cbc_deleteModel(model);
free(getname);
}

int main() {
printf("\nStarting C Interface test.\n\n");
char buildInfo[1024];
Expand Down Expand Up @@ -1115,5 +1205,9 @@ int main() {
testTSPUlysses22( 1 );
testTSPUlysses22( 0 );

printf("Dual reduction type test\n");
testDualReductionsType(LPR_Default);
testDualReductionsType(LPR_NoDualReds);

return 0;
}
Loading