#ifndef OSICLPSOLVER_BUILDER_HPP #define OSICLPSOLVER_BUILDER_HPP #include<functional> #include<vector> #include "coin/OsiClpSolverInterface.hpp" #include "coin/CoinPackedMatrix.hpp" class OsiClpSolver_Builder{ private: int nb_vars; struct VarType { int offset; int number; std::function<int (int[])> id; std::function<std::string (int)> id_toString; double lb; double ub; }; std::vector<VarType> varTypes; double * objective; double * col_lb; double * col_ub; std::vector<int> row_indices_buffer; std::vector<double> row_coeffs_buffer; std::vector<double> row_lb; std::vector<double> row_ub; CoinPackedMatrix * matrix; public: static const int MIN = 1; static const int MAX = -1; OsiClpSolver_Builder(); ~OsiClpSolver_Builder(); OsiClpSolver_Builder & addVarType(int number, std::function<int (int[])> id, std::function<std::string (int)> id_toString, double lb, double ub); void init(); double infty(); OsiClpSolver_Builder & setObjective(int var_id, double coef); OsiClpSolver_Builder & setBounds(int var_id, double lb, double ub); OsiClpSolver_Builder & buffEntry(int var_id, double coef); OsiClpSolver_Builder & pushRow(double lb, double ub); OsiClpSolverInterface * buildSolver(int sense); }; ///////////////////////// OsiClpSolver_Builder::OsiClpSolver_Builder() { this->nb_vars = 0; } OsiClpSolver_Builder::~OsiClpSolver_Builder() { delete[] objective; delete[] col_lb; delete[] col_ub; } OsiClpSolver_Builder & OsiClpSolver_Builder::addVarType(int number, std::function<int (int[])> id, std::function<std::string (int)> id_toString, double lb, double ub) { varTypes.push_back({nb_vars, number, id, id_toString, lb, ub}); this->nb_vars += number; return *this; } void OsiClpSolver_Builder::init() { objective = new double[nb_vars]; col_lb = new double[nb_vars]; col_ub = new double[nb_vars]; for(VarType varType : varTypes) { for(int i=varType.offset; i<varType.offset + varType.number; i++) { setObjective(i, 0); setBounds(i, varType.lb, varType.ub); } } matrix = new CoinPackedMatrix(false, 0, 0); matrix->setDimensions(0, nb_vars); } double OsiClpSolver_Builder::infty() { return OsiClpInfinity; } OsiClpSolver_Builder & OsiClpSolver_Builder::setObjective(int var_id, double coef) { objective[var_id] = coef; return *this; } OsiClpSolver_Builder & OsiClpSolver_Builder::setBounds(int var_id, double lb, double ub) { col_lb[var_id] = lb; col_ub[var_id] = ub; return *this; } OsiClpSolver_Builder & OsiClpSolver_Builder::buffEntry(int var_id, double coef) { row_indices_buffer.push_back(var_id); row_coeffs_buffer.push_back(coef); return *this; } OsiClpSolver_Builder & OsiClpSolver_Builder::pushRow(double lb, double ub) { matrix->appendRow(row_indices_buffer.size(), row_indices_buffer.data(), row_coeffs_buffer.data()); row_lb.push_back(lb); row_ub.push_back(ub); row_indices_buffer.clear(); row_coeffs_buffer.clear(); return *this; } OsiClpSolverInterface * OsiClpSolver_Builder::buildSolver(int sense) { OsiClpSolverInterface * solver = new OsiClpSolverInterface(); solver->loadProblem(*matrix, col_lb, col_ub, objective, row_lb.data(), row_ub.data()); solver->setObjSense(sense); return solver; } #endif //OSICLPSOLVER_BUILDER_HPP