Next, we move on to the OSI implementation that enables COPT to be used not only as an LPSolver but also as a MIPSolver. To use COPT as a MIPSolver, it must be explicitly instructed, and for that purpose, we have added a mode "mip" since the previous update. One note is we restricted one thread during mip mode.
#ifdef COPT #include "constraint_function.h" #includestatic copt_env* env = NULL; int OsiCOPTSolverInterface::error_handling(int errcode) const{ char errmsg[COPT_BUFFSIZE]; COPT_GetRetcodeMsg(errcode, errmsg, COPT_BUFFSIZE); string str = errmsg; str+="\n"; //printf("ERROR %d: %s\n", errcode, errmsg); send_status_to_gui(str); return 0; } OsiCOPTSolverInterface::OsiCOPTSolverInterface() { lpmethod = 2;//barrier int errcode = COPT_CreateEnv(&env); if (errcode) { error_handling(errcode); } else { errcode = COPT_CreateProb(env, &prob); if (errcode) { error_handling(errcode); } errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LOGTOCONSOLE, 0);// COPT_INTPARAM_LOGGING, 0); if (errcode) { error_handling(errcode); } errcode=COPT_SetIntParam(prob, COPT_INTPARAM_CROSSOVER, 0);//crossover 禁止 if (errcode) { error_handling(errcode); } errcode= COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, lpmethod);//barrier if (errcode) { error_handling(errcode); } } //*get_model() = env.CreateModel("lp_ex1"); mip_obj = DBL_MAX; running = false; crossover = true; log_cnt = 0; mip = false; } OsiCOPTSolverInterface& OsiCOPTSolverInterface::operator=(const OsiCOPTSolverInterface& rhs) { int errcode=COPT_CreateCopy(rhs.get_prob(), &prob); objOffset = rhs.objOffset; running = rhs.running; crossover = rhs.crossover; col_lower_vec = rhs.col_lower_vec; col_upper_vec=rhs.col_upper_vec; row_lower_vec = rhs.row_lower_vec; row_upper_vec =rhs.row_upper_vec; col_cost_vec=rhs.col_cost_vec; lpmethod = rhs.lpmethod; mip = rhs.mip; errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LOGTOCONSOLE, 0);// COPT_INTPARAM_LOGGING, 0); if (errcode) { error_handling(errcode); } return *this; } OsiCOPTSolverInterface::OsiCOPTSolverInterface(const OsiCOPTSolverInterface& original) { *this = original; } OsiCOPTSolverInterface::~OsiCOPTSolverInterface() { // Delete problem and environment if (prob) { COPT_DeleteProb(&prob); } if (env) { COPT_DeleteEnv(&env); } mip_obj = DBL_MAX; running = false; crossover = true; log_cnt = 0; } void OsiCOPTSolverInterface::set_mip() { mip = true; int errcode = COPT_SetIntParam(prob, COPT_INTPARAM_THREADS,1); if (errcode) { error_handling(errcode); } } /// Get objective function sense (1 for min (default), -1 for max) double OsiCOPTSolverInterface::getObjSense() const { return 1;//min } void OsiCOPTSolverInterface::set_time_limit(int sec) { //HighsStatus hs = this->highs->setOptionValue("time_limit", sec); int errcode = COPT_SetDblParam(prob, COPT_DBLPARAM_TIMELIMIT, sec); if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::setObjSense(double s) { ObjSense pass_sense = ObjSense::kMinimize; if (s == (double)ObjSense::kMaximize) pass_sense = ObjSense::kMaximize; if (pass_sense == ObjSense::kMinimize) { int errcode=COPT_SetObjSense(prob, COPT_MINIMIZE); if (errcode) { error_handling(errcode); } } else { int errcode = COPT_SetObjSense(prob, COPT_MAXIMIZE); if (errcode) { error_handling(errcode); } } } void OsiCOPTSolverInterface::writeMps(const char* filename, const char* extension, double objSense) const { std::string fullname = std::string(filename) + "." + std::string(extension); int errcode=COPT_WriteMps( prob, fullname.c_str()); if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::writeLp(const char* filename, const char* extension, double objSense) const { std::string fullname = std::string(filename) + "." + std::string(extension); int errcode = COPT_WriteLp(prob, fullname.c_str()); if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::setRowType(HighsInt index, char sense, double rightHandSide, double range) { // Assign arbitrary values so that compilation is clean double lo = 0; double hi = 1e200; this->convertSenseToBound(sense, rightHandSide, range, lo, hi); this->setRowBounds(index, lo, hi); } void OsiCOPTSolverInterface::setObjCoeff(HighsInt elementIndex, double elementValue) { int errcode=COPT_SetColObj(prob, 1,&elementIndex, &elementValue); if (errcode) { error_handling(errcode); } //this->highs->changeColCost(elementIndex, elementValue); } void OsiCOPTSolverInterface::setObjCoeffSet(const int* indexFirst, const int* indexLast, const double* coeffList) { OsiSolverInterface::setObjCoeffSet(indexFirst, indexLast - 1, coeffList); } void OsiCOPTSolverInterface::setColSetBounds(const HighsInt* indexFirst, const HighsInt* indexLast, const double* boundList) { OsiSolverInterface::setColSetBounds(indexFirst, indexLast - 1, boundList); } void OsiCOPTSolverInterface::setRowBounds(HighsInt elementIndex, double lower, double upper) { int errcode=COPT_SetRowLower(prob, 1, &elementIndex, &lower); if (errcode) { error_handling(errcode); } errcode = COPT_SetRowUpper(prob, 1, &elementIndex, &upper); if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::setColBounds(HighsInt elementIndex, double lower, double upper) { int errcode = COPT_SetColLower(prob, 1, &elementIndex, &lower); if (errcode) { error_handling(errcode); } errcode = COPT_SetColUpper(prob, 1, &elementIndex, &upper); if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::setRowSetBounds(const HighsInt* indexFirst, const HighsInt* indexLast, const double* boundList) { OsiSolverInterface::setRowSetBounds(indexFirst, indexLast - 1, boundList); } void OsiCOPTSolverInterface::branchAndBound() { // TODO } void OsiCOPTSolverInterface::set_lpmethod(int m,double d) { lpmethod = m; if (lpmethod == 6) { send_status_to_gui("\t\tPDLP is selected.\n"); int errcode = COPT_SetDblParam(prob, COPT_DBLPARAM_PDLPTOL, d);//Barrier if (errcode) { error_handling(errcode); } errcode = COPT_SetIntParam(prob, COPT_INTPARAM_GPUMODE, 1);//GPU mode=1 if (errcode) { error_handling(errcode); } } else if (lpmethod == 2) { send_status_to_gui("\t\tBarrier is selected.\n"); int errcode = COPT_SetIntParam(prob, COPT_INTPARAM_GPUMODE, 0);//GPU mode=0 if (errcode) { error_handling(errcode); } //errcode = COPT_SetIntParam(prob, COPT_INTPARAM_GPUMODE, 1);//GPU mode=1 } } void OsiCOPTSolverInterface::initialSolve() { if (mip) { int errcode = COPT_Solve(prob); if (errcode) { error_handling(errcode); } int lpstat = COPT_MIPSTATUS_UNSTARTED; errcode = COPT_GetIntAttr(prob, COPT_INTATTR_MIPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } if (lpstat == COPT_MIPSTATUS_OPTIMAL) { sol.col_value.resize(getNumCols()); int errcode = COPT_GetSolution(prob, &sol.col_value[0]);// //int COPT_GetLpSolution(copt_prob * prob, double* value, double * slack(activity of constraints), double* rowDual(row price), double* redCost) if (errcode) { error_handling(errcode); } } return; } set_running(true); int errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, lpmethod);//Barrier if (errcode) { error_handling(errcode); } Restart: errcode = COPT_SolveLp(prob); if (errcode) { error_handling(errcode); } int lpstat = COPT_LPSTATUS_UNSTARTED; double lpobjval; double* lpsol = NULL; int* colstat = NULL; errcode = COPT_GetIntAttr(prob, COPT_INTATTR_LPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } if (lpstat == COPT_LPSTATUS_OPTIMAL) { sol.col_value.resize(getNumCols()); sol.col_dual.resize(getNumCols()); sol.row_dual.resize(getNumRows()); sol.row_value.resize(getNumRows()); //getRowActivity int errcode = COPT_GetLpSolution(prob, &sol.col_value[0], &sol.row_value[0], &sol.row_dual[0], &sol.col_dual[0]);// //int COPT_GetLpSolution(copt_prob * prob, double* value, double * slack(activity of constraints), double* rowDual(row price), double* redCost) if (errcode) { error_handling(errcode); } } else if (lpstat == COPT_LPSTATUS_NUMERICAL) { string str = "Numarical trouble encounterd.\n"; send_status_to_gui(str); //writeMps("copt_trouble1"); errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD,0);//Simplex if (errcode) { error_handling(errcode); } goto Restart; errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, lpmethod);//Barrier if (errcode) { error_handling(errcode); } } else assert(0); errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, lpmethod);//Barrier if (errcode) { error_handling(errcode); } //this->status = this->highs->run(); //const HighsSolution const_sol = this->highs->getSolution(); //sol = const_sol; set_running(false); } void OsiCOPTSolverInterface::resolve() { initialSolve(); } const double* OsiCOPTSolverInterface::getRowRange() const { if (this->rowRange != NULL) { delete[] this->rowRange; } HighsInt nrows = this->getNumRows(); if (nrows == 0) { return this->rowRange; } this->rowRange = new double[nrows]; for (HighsInt i = 0; i < nrows; i++) { // compute range for row i double lo = this->getRowLower()[i]; double hi = this->getRowUpper()[i]; double t1; char t2; this->convertBoundToSense(lo, hi, t2, t1, this->rowRange[i]); } return this->rowRange; } const double* OsiCOPTSolverInterface::getRightHandSide() const { # if (this->rhs != NULL) { delete[] this->rhs; } HighsInt nrows = this->getNumRows(); if (nrows == 0) { return this->rhs; } this->rhs = new double[nrows]; for (HighsInt i = 0; i < nrows; i++) { // compute rhs for row i double lo = this->getRowLower()[i]; double hi = this->getRowUpper()[i]; double t1; char t2; this->convertBoundToSense(lo, hi, t2, this->rhs[i], t1); } return this->rhs; } const char* OsiCOPTSolverInterface::getRowSense() const { if (this->rowSense != NULL) { delete[] this->rowSense; } HighsInt nrows = this->getNumRows(); if (nrows == 0) { return this->rowSense; } this->rowSense = new char[nrows]; for (HighsInt i = 0; i < nrows; i++) { // compute sense for row i double lo = this->getRowLower()[i]; double hi = this->getRowUpper()[i]; double t1, t2; this->convertBoundToSense(lo, hi, this->rowSense[i], t1, t2); } return this->rowSense; } void OsiCOPTSolverInterface::make_crossover() { double d1 = getObjValue(); { if (d1 == 0) { resolve(); } int errcode = COPT_SetIntParam(prob, COPT_INTPARAM_CROSSOVER, 1);//crossover Enable if (errcode) { error_handling(errcode); } errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, 3);//crossover if (errcode) { error_handling(errcode); } } /* 1: Dual simplex. 2 : Barrier. 3 : Crossover. 4 : Concurrent(Use simplex and barrier simultaneously). 5 : Choose between simplex and barrier automatically(Based on features such as sparsity and /or coefficients ranges). 6 : First - order method(PDLP) */ resolve(); double d2 = getObjValue(); if (d1) { // assert(fabs(d1 - d2) <= 1e-3); } { int errcode = COPT_SetIntParam(prob, COPT_INTPARAM_CROSSOVER, 0);//crossover 禁止 if (errcode) { error_handling(errcode); } errcode = COPT_SetIntParam(prob, COPT_INTPARAM_LPMETHOD, lpmethod);//barrier if (errcode) { error_handling(errcode); } } } const CoinPackedMatrix* OsiCOPTSolverInterface::getMatrixByCol() const { if (this->matrixByCol != NULL) { delete this->matrixByCol; } HighsInt nrows = this->getNumRows(); HighsInt ncols = this->getNumCols(); HighsInt nelements = this->getNumElements(); HighsInt* len = new int[ncols]; HighsInt* start = new int[ncols + 1]; HighsInt* index = new int[nelements]; double* value = new double[nelements]; int pReqSize = 0; /* int errcode = COPT_GetCols(prob, ncols, 0,//const int* list, 0,//int* colMatBeg, 0,//int* colMatCnt, 0,// int* colMatIdx, 0,//double* colMatElem, nelements, &pReqSize);*/ //vector list; //for (auto i = 0; i < ncols; i++) { // list.push_back(i); //} int errcode = COPT_GetCols(prob, ncols, 0,//const int* list, start,//int* colMatBeg, 0,// lenは0で渡すFORMATにする,//int* colMatCnt, index,// int* colMatIdx, value,//double* colMatElem, nelements, &pReqSize); // copy data //assert(0);//TODO /* memcpy(start, &(this->highs->getLp().a_matrix_.start_[0]), (ncols + 1) * sizeof(HighsInt)); memcpy(index, &(this->highs->getLp().a_matrix_.index_[0]), nelements * sizeof(HighsInt)); memcpy(value, &(this->highs->getLp().a_matrix_.value_[0]), nelements * sizeof(double)); */ if (errcode) { error_handling(errcode); } for (HighsInt i = 0; i < ncols; i++) {// assert(start[i + 1] >= 0); len[i] = start[i + 1] - start[i]; } this->matrixByCol = new CoinPackedMatrix(); this->matrixByCol->assignMatrix(true, nrows, ncols, nelements, value, index, start, len); assert(this->matrixByCol->getNumCols() == ncols); assert(this->matrixByCol->getNumRows() == nrows); return this->matrixByCol; } const CoinPackedMatrix* OsiCOPTSolverInterface::getMatrixByRow() const { if (this->matrixByRow != NULL) { delete this->matrixByRow; } this->matrixByRow = new CoinPackedMatrix(); this->matrixByRow->reverseOrderedCopyOf(*this->getMatrixByCol()); return this->matrixByRow; } void OsiCOPTSolverInterface::assignProblem(CoinPackedMatrix*& matrix, double*& collb, double*& colub, double*& obj, double*& rowlb, double*& rowub) { loadProblem(*matrix, collb, colub, obj, rowlb, rowub); delete matrix; matrix = 0; delete[] collb; collb = 0; delete[] colub; colub = 0; delete[] obj; obj = 0; delete[] rowlb; rowlb = 0; delete[] rowub; rowub = 0; } void OsiCOPTSolverInterface::loadProblem(const CoinPackedMatrix& matrix, const double* collb, const double* colub, const double* obj, const char* rowsen, const double* rowrhs, const double* rowrng) { HighsInt numRow = matrix.getNumRows(); double* rowlb = new double[numRow]; double* rowub = new double[numRow]; char* myrowsen = (char*)rowsen; bool rowsennull = false; double* myrowrhs = (double*)rowrhs; bool rowrhsnull = false; double* myrowrng = (double*)rowrng; bool rowrngnull = false; if (rowsen == NULL) { rowsennull = true; myrowsen = new char[numRow]; for (HighsInt i = 0; i < numRow; i++) { myrowsen[i] = 'G'; } } if (rowrhs == NULL) { rowsennull = true; myrowrhs = new double[numRow]; for (HighsInt i = 0; i < numRow; i++) { myrowrhs[i] = 0.0; } } if (rowrng == NULL) { rowrngnull = true; myrowrng = new double[numRow]; for (HighsInt i = 0; i < numRow; i++) { myrowrng[i] = 0.0; } } for (HighsInt i = 0; i < numRow; i++) { this->convertSenseToBound(myrowsen[i], myrowrhs[i], myrowrng[i], rowlb[i], rowub[i]); } this->loadProblem(matrix, collb, colub, obj, rowlb, rowub); delete[] rowlb; delete[] rowub; if (rowsennull) { delete[] myrowsen; } if (rowrhsnull) { delete[] myrowrhs; } if (rowrngnull) { delete[] myrowrng; } } void OsiCOPTSolverInterface::assignProblem(CoinPackedMatrix*& matrix, double*& collb, double*& colub, double*& obj, char*& rowsen, double*& rowrhs, double*& rowrng) { loadProblem(*matrix, collb, colub, obj, rowsen, rowrhs, rowrng); delete matrix; matrix = 0; delete[] collb; collb = 0; delete[] colub; colub = 0; delete[] obj; obj = 0; delete[] rowsen; rowsen = 0; delete[] rowrhs; rowrhs = 0; delete[] rowrng; rowrng = 0; } void OsiCOPTSolverInterface::loadProblem( const HighsInt numcols, const HighsInt numrows, const CoinBigIndex* start, const HighsInt* index, const double* value, const double* collb, const double* colub, const double* obj, const double* rowlb, const double* rowub) { double oldObjSense = this->getObjSense(); //obj if (obj == 0) { col_cost_vec.clear(); } else { col_cost_vec.resize(numcols); for (auto i = 0; i < numcols; i++) { col_cost_vec[i] = obj[i]; } } //col col_lower_vec.resize(numcols); col_upper_vec.resize(numcols); for (auto i = 0; i < numcols; i++) { col_lower_vec[i] = collb[i]; col_upper_vec[i] = colub[i]; } //row row_lower_vec.resize(numrows); row_upper_vec.resize(numrows); for (auto i = 0; i < numrows; i++) { row_lower_vec[i] = rowlb[i]; row_upper_vec[i] = rowub[i]; } int errcode = COPT_LoadProb(prob, numcols, numrows, COPT_MINIMIZE,//The optimization sense, either COPT_MAXIMIZE or COPT_MINIMIZE. objOffset,//The constant part of the objective function. obj,//Objective coefficients of variables start, 0,//const int* colMatCnt, //If colMatCnt is NULL, colMatBeg will need to have length of nCol+1,and the begin and end pointers to the i - th matrix column coefficients are defined using colMatBeg[i] and colMatBeg[i + 1] index,//const int* colMatIdx, value,//const double* colMatElem, 0,//const char* colType, //If colType is NULL, all variables will be continuous. collb, // const double* colLower, colub,//const double* colUpper, 0,//const char* rowSense,//If rowSense is NULL, then rowBound and rowUpper will be treated as lower and upper bounds for constraints.T rowlb,//const double* rowBound, rowub,// double* rowUpper, 0,//char const* const* colNames,// 0);// char const* const* rowNames);Names of variables and constraints. Can be NULL if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::loadProblem( const HighsInt numcols, const HighsInt numrows, const CoinBigIndex* start, const HighsInt* index, const double* value, const double* collb, const double* colub, const double* obj, const char* rowsen, const double* rowrhs, const double* rowrng) { double* rowlb = new double[numrows]; double* rowub = new double[numrows]; for (HighsInt i = 0; i < numrows; i++) { this->convertSenseToBound(rowsen[i], rowrhs[i], rowrng[i], rowlb[i], rowub[i]); } this->loadProblem(numcols, numrows, start, index, value, collb, colub, obj, rowlb, rowub); delete[] rowlb; delete[] rowub; } void OsiCOPTSolverInterface::loadProblem( const CoinPackedMatrix& matrix, const double* collb, const double* colub, const double* obj, const double* rowlb, const double* rowub) { bool transpose = false; if (!matrix.isColOrdered()) { transpose = true; // ToDo: remove this hack //((CoinPackedMatrix *)&matrix)->transpose(); ((CoinPackedMatrix*)&matrix)->reverseOrdering(); } HighsInt numCol = matrix.getNumCols(); HighsInt numRow = matrix.getNumRows(); HighsInt num_nz = matrix.getNumElements(); HighsInt* start = new int[numCol + 1]; HighsInt* index = new int[num_nz]; double* value = new double[num_nz]; // get matrix data // const CoinBigIndex *vectorStarts = matrix.getVectorStarts(); const HighsInt* vectorLengths = matrix.getVectorLengths(); const double* elements = matrix.getElements(); const HighsInt* indices = matrix.getIndices(); // set matrix in HighsLp start[0] = 0; HighsInt nz = 0; for (HighsInt i = 0; i < numCol; i++) { start[i + 1] = start[i] + vectorLengths[i]; CoinBigIndex first = matrix.getVectorFirst(i); for (HighsInt j = 0; j < vectorLengths[i]; j++) { index[nz] = indices[first + j]; value[nz] = elements[first + j]; nz++; } } assert(num_nz == nz); this->loadProblem(numCol, numRow, start, index, value, collb, colub, obj, rowlb, rowub); if (transpose) { //((CoinPackedMatrix)matrix).transpose(); ((CoinPackedMatrix*)&matrix)->reverseOrdering(); } delete[] start; delete[] index; delete[] value; } void OsiCOPTSolverInterface::addRow(const CoinPackedVectorBase& vec, const double rowlb, const double rowub) { int errcode = COPT_AddRow(prob, vec.getNumElements(), vec.getIndices(), vec.getElements(), 0, rowlb, rowub, 0); if (errcode) { error_handling(errcode); } else { row_lower_vec.push_back(rowlb); row_upper_vec.push_back(rowub); } } void OsiCOPTSolverInterface::addRow(const CoinPackedVectorBase& vec, const char rowsen, const double rowrhs, const double rowrng) { // Assign arbitrary values so that compilation is clean double lb = 0; double ub = 1e200; this->convertSenseToBound(rowsen, rowrhs, rowrng, lb, ub); this->addRow(vec, lb, ub); } void OsiCOPTSolverInterface::addCol(const CoinPackedVectorBase& vec, const double collb, const double colub, const double obj) { int elements = vec.getNumElements(); const int* index_ptr = vec.getIndices(); const double* val_ptr = vec.getElements(); int errcode = COPT_AddCol(prob, obj, elements, index_ptr,val_ptr, COPT_CONTINUOUS, collb, colub, 0);//Variable Type: 'C' if (errcode) { error_handling(errcode); } else { col_cost_vec.push_back(obj); col_lower_vec.push_back(collb); col_upper_vec.push_back(colub); } } void OsiCOPTSolverInterface::deleteCols(const HighsInt num, const HighsInt* colIndices) { int originalcols = getNumCols(); assert(col_cost_vec.size() == getNumCols()); int errcode = COPT_DelCols(prob, num, colIndices); if (errcode) { error_handling(errcode); } else { getColLowerCOPT(); getColUpperCOPT(); getObjCoefficientsCOPT(); /* set del_set; for (int i = 0; i < num; i++) { int ind = colIndices[i]; del_set.insert(ind); } vector new_col_cost_vec; vector new_col_upper, new_col_lower; for (int i = 0; i < originalcols; i++) { auto iter = del_set.find(i); if (iter == del_set.end()) { new_col_cost_vec.push_back(col_cost_vec[i]); new_col_lower.push_back(col_lower_vec[i]); new_col_upper.push_back(col_upper_vec[i]); } } assert(num == del_set.size()); assert(col_cost_vec.size() == new_col_cost_vec.size() + del_set.size()); col_cost_vec = new_col_cost_vec; col_lower_vec = new_col_lower; col_upper_vec = new_col_upper; assert(col_cost_vec.size() == col_lower_vec.size()); assert(col_cost_vec.size() == col_upper_vec.size()); assert(col_cost_vec.size() == getNumCols()); */ } } void OsiCOPTSolverInterface::deleteRows(const HighsInt num, const HighsInt* rowIndices) { int originalrows = getNumRows(); int errcode = COPT_DelRows(prob, num, rowIndices); if (errcode) { error_handling(errcode); } else { getRowLowerCOPT(); getRowUpperCOPT(); /* set del_set; for (int i = 0; i < num; i++) { int ind = rowIndices[i]; del_set.insert(ind); } vector new_row_upper, new_row_lower; for (int i = 0; i < originalrows; i++) { auto iter = del_set.find(i); if (iter == del_set.end()) { new_row_lower.push_back(row_lower_vec[i]); new_row_upper.push_back(row_upper_vec[i]); } } assert(num == del_set.size()); assert(row_lower_vec.size() == new_row_lower.size() + del_set.size()); row_lower_vec = new_row_lower; row_upper_vec = new_row_upper; assert(row_lower_vec.size() == getNumRows()); */ } } bool OsiCOPTSolverInterface::isContinuous(int colNumber) const { char b; int errcode=COPT_GetColType(prob,1, &colNumber, &b); if (errcode) { error_handling(errcode); } return b== COPT_CONTINUOUS; } double OsiCOPTSolverInterface::getObjValue() const { double lpobjval; if (mip) { int errcode = COPT_GetDblAttr(prob, COPT_DBLATTR_BESTOBJ, &lpobjval); if (errcode) { error_handling(errcode); } return lpobjval; } int errcode = COPT_GetDblAttr(prob, COPT_DBLATTR_LPOBJVAL, &lpobjval); if (errcode) { error_handling(errcode); } return lpobjval; } bool OsiCOPTSolverInterface::isAbandoned() const { return false; } bool OsiCOPTSolverInterface::isProvenOptimal() const { if (mip) { int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_MIPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } if (lpstat == COPT_MIPSTATUS_OPTIMAL) { return true; } assert(0); return false; } int* colstat = NULL; int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_LPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } return lpstat== COPT_LPSTATUS_OPTIMAL; } bool OsiCOPTSolverInterface::isProvenPrimalInfeasible() const { if (mip) { int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_MIPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } if (lpstat == COPT_MIPSTATUS_INFEASIBLE) { return true; } return false; } int* colstat = NULL; int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_LPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } return lpstat == COPT_LPSTATUS_INFEASIBLE; } bool OsiCOPTSolverInterface::isProvenDualInfeasible() const { assert(!mip); int* colstat = NULL; int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_LPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } return lpstat == COPT_LPSTATUS_INFEASIBLE; } bool OsiCOPTSolverInterface::isPrimalObjectiveLimitReached() const { return false; } bool OsiCOPTSolverInterface::isDualObjectiveLimitReached() const { return false; } bool OsiCOPTSolverInterface::isIterationLimitReached() const { int* colstat = NULL; int lpstat = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_LPSTATUS, &lpstat); if (errcode) { error_handling(errcode); } return lpstat == COPT_LPSTATUS_ITERLIMIT; } HighsInt OsiCOPTSolverInterface::getIterationCount() const { int iteration_count = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_BARRIERITER, &iteration_count); if (errcode) { error_handling(errcode); } return iteration_count; } HighsInt OsiCOPTSolverInterface::getNumCols() const { int elems = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_COLS, &elems); if (errcode) { error_handling(errcode); } return elems; } HighsInt OsiCOPTSolverInterface::getNumRows() const { int elems = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_ROWS, &elems); if (errcode) { error_handling(errcode); } return elems; } HighsInt OsiCOPTSolverInterface::getNumElements() const { int elems = 0; int errcode = COPT_GetIntAttr(prob, COPT_INTATTR_ELEMS, &elems); if (errcode) { error_handling(errcode); } return elems; } void OsiCOPTSolverInterface::setRowLower(HighsInt elementIndex, double elementValue) { int errcode = COPT_SetRowLower(prob, 1, &elementIndex, &elementValue); if (errcode) { error_handling(errcode); } else { assert(elementIndex < row_lower_vec.size()); row_lower_vec[elementIndex] = elementValue; } } void OsiCOPTSolverInterface::setRowUpper(HighsInt elementIndex, double elementValue) { int errcode = COPT_SetRowUpper(prob, 1, &elementIndex, &elementValue); if (errcode) { error_handling(errcode); } else { assert(elementIndex < row_upper_vec.size()); row_upper_vec[elementIndex] = elementValue; } } void OsiCOPTSolverInterface::setColLower(HighsInt elementIndex, double elementValue) { int errcode = COPT_SetColLower(prob, 1, &elementIndex, &elementValue); if (errcode) { error_handling(errcode); } else { assert(elementIndex < col_lower_vec.size()); col_lower_vec[elementIndex] = elementValue; } } void OsiCOPTSolverInterface::setColUpper(HighsInt elementIndex, double elementValue) { int errcode = COPT_SetColUpper(prob, 1, &elementIndex, &elementValue); if (errcode) { error_handling(errcode); } else { assert(elementIndex < col_upper_vec.size()); col_upper_vec[elementIndex] = elementValue; } } void OsiCOPTSolverInterface::setContinuous(int index) { const char b = COPT_CONTINUOUS; int errcode=COPT_SetColType(prob, 1, &index, &b); if (errcode) { error_handling(errcode); } } /// Set the index-th variable to be an integer variable void OsiCOPTSolverInterface::setInteger(int index) { const char b = COPT_INTEGER; int errcode = COPT_SetColType(prob, 1, &index, &b); if (errcode) { error_handling(errcode); } } const double* OsiCOPTSolverInterface::getColLower() const { assert(col_lower_vec.size()); return &col_lower_vec[0]; } const double* OsiCOPTSolverInterface::getColLowerCOPT() { col_lower_vec.resize(getNumCols(),0); int errcode = COPT_GetColInfo(prob, COPT_DBLINFO_LB, getNumCols(), 0, &col_lower_vec[0]); if (errcode) { error_handling(errcode); } return &col_lower_vec[0]; } const double* OsiCOPTSolverInterface::getColUpper() const { assert(col_upper_vec.size()); return &col_upper_vec[0]; } const double* OsiCOPTSolverInterface::getColUpperCOPT() { //assert(col_upper_vec.size() == getNumCols()); col_upper_vec.resize(getNumCols(), 0); int errcode = COPT_GetColInfo(prob, COPT_DBLINFO_UB, getNumCols(), 0, &col_upper_vec[0]); if (errcode) { error_handling(errcode); } return &col_upper_vec[0]; } const double* OsiCOPTSolverInterface::getRowLowerCOPT() { //assert(row_lower_vec.size()==getNumRows()); row_lower_vec.resize(getNumRows(), 0); int errcode = COPT_GetRowInfo(prob, COPT_DBLINFO_LB, getNumRows(), 0, &row_lower_vec[0]); if (errcode) { error_handling(errcode); } return &row_lower_vec[0]; } bool OsiCOPTSolverInterface::compare( OsiCOPTSolverInterface& copt) { if (getNumCols() != copt.getNumCols()) { return false; } if (getNumRows() != copt.getNumRows()) { return false; } getObjCoefficientsCOPT(); copt.getObjCoefficientsCOPT(); getColUpperCOPT(); copt.getColUpperCOPT(); getColLowerCOPT(); copt.getColLowerCOPT(); getRowUpperCOPT(); copt.getRowUpperCOPT(); getRowLowerCOPT(); copt.getRowLowerCOPT(); const CoinPackedMatrix* cp = getMatrixByCol(); const CoinPackedMatrix* cp1 = copt.getMatrixByCol(); bool identical2 = cp->isEquivalent(*cp1); if (!identical2) { assert(0); return false; } for (auto i = 0; i < getNumRows(); i++) { double obj1 = getRowLower()[i]; double obj2 = copt.getRowLower()[i]; if (fabs(obj1 - obj2) >= 1e-3) { assert(0); return false; } obj1 = getRowUpper()[i]; obj2 = copt.getRowUpper()[i]; if (fabs(obj1 - obj2) >= 1e-3) { assert(0); return false; } } for (auto i = 0; i < getNumCols(); i++) { double obj1 = getObjCoefficients()[i]; double obj2 = copt.getObjCoefficients()[i]; if (fabs(obj1 - obj2) >= 1e-3) { assert(0); return false; } obj1 = getColLower()[i]; obj2 = copt.getColLower()[i]; if (fabs(obj1 - obj2) >= 1e-3) { assert(0); return false; } obj1 = getColUpper()[i]; obj2 = copt.getColUpper()[i]; if (obj1 >= 1e30 && obj2 >= 1e30) { continue; } if (fabs(obj1 - obj2) >= 1e-3) { assert(0); return false; } } return true; } const double* OsiCOPTSolverInterface::getRowUpperCOPT() { row_upper_vec.resize(getNumRows(), 0); //assert(row_upper_vec.size() == getNumRows()); int errcode = COPT_GetRowInfo(prob, COPT_DBLINFO_UB, getNumRows(), 0, &row_upper_vec[0]); if (errcode) { error_handling(errcode); } return &row_upper_vec[0]; } const double* OsiCOPTSolverInterface::getObjCoefficientsCOPT() { // assert(col_cost_vec.size()); //assert(col_cost_vec.size() == getNumCols()); col_cost_vec.resize(getNumCols(), 0); int errcode = COPT_GetColInfo(prob, COPT_DBLINFO_OBJ, getNumCols(), 0, &col_cost_vec[0]); if (errcode) { error_handling(errcode); } return &col_cost_vec[0]; } const double* OsiCOPTSolverInterface::getRowLower() const { assert(row_lower_vec.size()); return &row_lower_vec[0]; } const double* OsiCOPTSolverInterface::getRowUpper() const { assert(row_upper_vec.size()); return &row_upper_vec[0]; } const double* OsiCOPTSolverInterface::getObjCoefficients() const { assert(col_cost_vec.size()); return &col_cost_vec[0]; } // TODO: review: 10^20? double OsiCOPTSolverInterface::getInfinity() const { return kHighsInf; } const double* OsiCOPTSolverInterface::getColSolution() const { const double* ptr = &sol.col_value[0]; return ptr; } const double* OsiCOPTSolverInterface::getRowPrice() const { return &sol.row_dual[0]; } const double* OsiCOPTSolverInterface::getReducedCost() const { return &sol.col_dual[0]; } const double* OsiCOPTSolverInterface::getRowActivity() const { return &sol.row_value[0]; } int OsiCOPTSolverInterface::setBasisStatus(const int*colbasis, const int*rowbasis) { int errcode = COPT_SetBasis(prob, colbasis, rowbasis); if (errcode) { error_handling(errcode); } return 0; } void OsiCOPTSolverInterface::getBasisStatus(HighsInt* cstat, HighsInt* rstat) const { int errcode=COPT_GetBasis(prob,cstat,rstat); if (errcode) { error_handling(errcode); } } OsiSolverInterface* OsiCOPTSolverInterface::clone(bool copyData) const { if (!copyData) { OsiCOPTSolverInterface* cln = new OsiCOPTSolverInterface(); return cln; } else { OsiCOPTSolverInterface* cln = new OsiCOPTSolverInterface(*this); return cln; } } void OsiCOPTSolverInterface::setRowPrice(const double* rowprice) { assert(getNumRows() == sol.row_dual.size()); for (auto i = 0; i < getNumRows(); i++) { sol.row_value[i] = rowprice[i]; } int errcode = COPT_SetLpSolution(prob, &sol.col_value[0], &sol.row_value[0], &sol.row_dual[0], &sol.col_dual[0]);// //int COPT_GetLpSolution(copt_prob * prob, double* value, double * slack(activity of constraints), double* rowDual(row price), double* redCost) if (errcode) { error_handling(errcode); } } void OsiCOPTSolverInterface::setColSolution(const double* colsol) { assert(getNumCols() == sol.col_value.size()); for (auto i = 0; i < getNumCols(); i++) { sol.col_value[i] = colsol[i]; } int errcode = COPT_SetLpSolution(prob, &sol.col_value[0], &sol.row_value[0], &sol.row_dual[0], &sol.col_dual[0]);// //int COPT_GetLpSolution(copt_prob * prob, double* value, double * slack(activity of constraints), double* rowDual(row price), double* redCost) if (errcode) { error_handling(errcode); } } std::vector OsiCOPTSolverInterface::getDualRays(HighsInt maxNumRays, bool fullRay) const { assert(0); return std::vector (0); } std::vector OsiCOPTSolverInterface::getPrimalRays( HighsInt maxNumRays) const { assert(0); return std::vector (0); } CoinWarmStart* OsiCOPTSolverInterface::getEmptyWarmStart() const { return 0; } CoinWarmStart* OsiCOPTSolverInterface::getWarmStart() const { return 0; } bool OsiCOPTSolverInterface::setWarmStart(const CoinWarmStart* warmstart) { //const HighsOptions& options = this->highs->getOptions(); //highsLogDev(options.log_options, HighsLogType::kInfo, // "Calling OsiHiGHSSolverInterface::setWarmStart()\n"); return false; } #endif
0 件のコメント:
コメントを投稿