Skip to content
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
21 changes: 11 additions & 10 deletions include/scippp/model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <algorithm>
#include <array>
#include <functional>
#include <optional>
#include <scip/scip.h>
#include <string>
#include <type_traits>
Expand Down Expand Up @@ -86,16 +87,16 @@ class Model {
* @param name of the variable when the model is written.
* @param coeff Coefficient in the objective function.
* @param varType variable type.
* @param lb lower bound.
* @param ub upper bound.
* @param lb lower bound. \c std::nullopt is interpreted as -infinity.
* @param ub upper bound. \c std::nullopt is interpreted as infinity.
* @return Reference to the newly created variable.
*/
Var& addVar(
const std::string& name,
SCIP_Real coeff = 0.0,
VarType varType = VarType::CONTINUOUS,
SCIP_Real lb = 0.0,
SCIP_Real ub = 1.0);
std::optional<SCIP_Real> lb = 0.0,
std::optional<SCIP_Real> ub = 1.0);

/**
* Adds multiple variables to the model.
Expand All @@ -106,8 +107,8 @@ class Model {
* @param numVars number of variables to create.
* @param coeffs Object holding the coefficients for the objective function.
* @param varType variable type.
* @param lb lower bound.
* @param ub upper bound.
* @param lb lower bound. \c std::nullopt is interpreted as -infinity.
* @param ub upper bound. \c std::nullopt is interpreted as infinity.
* @return Vector of variables.
*/
template <typename CoeffType = ConstantCoefficient>
Expand All @@ -116,8 +117,8 @@ class Model {
size_t numVars,
const CoeffType& coeffs = COEFF_ZERO,
VarType varType = VarType::CONTINUOUS,
SCIP_Real lb = 0.0,
SCIP_Real ub = 1.0)
std::optional<SCIP_Real> lb = 0.0,
std::optional<SCIP_Real> ub = 1.0)
{
std::vector<Var> result;
result.reserve(numVars);
Expand Down Expand Up @@ -149,8 +150,8 @@ class Model {
const std::string& prefix,
const CoeffType& coeffs = COEFF_ZERO,
VarType varType = VarType::CONTINUOUS,
SCIP_Real lb = 0.0,
SCIP_Real ub = 1.0)
std::optional<SCIP_Real> lb = 0.0,
std::optional<SCIP_Real> ub = 1.0)
{
std::array<Var, NumVars> result;
auto vec { addVars(prefix, NumVars, coeffs, varType, lb, ub) };
Expand Down
11 changes: 8 additions & 3 deletions source/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@

namespace scippp {

Var& Model::addVar(const std::string& name, SCIP_Real coeff, VarType varType, SCIP_Real lb, SCIP_Real ub)
Var& Model::addVar(
const std::string& name,
SCIP_Real coeff,
VarType varType,
std::optional<SCIP_Real> lb,
std::optional<SCIP_Real> ub)
{
SCIP_VAR* var { nullptr };
m_scipCallWrapper(SCIPcreateVarBasic(
m_scip, /* SCIP environment */
&var, /* reference to the variable */
name.c_str(), /* name of the variable */
lb, /* lower bound of the variable */
ub, /* upper bound of the variable */
lb != std::nullopt ? lb.value() : -SCIPinfinity(m_scip), /* lower bound of the variable */
ub != std::nullopt ? ub.value() : SCIPinfinity(m_scip), /* upper bound of the variable */
coeff, /* obj. coefficient. */
static_cast<SCIP_Vartype>(varType) /* variable is binary */
));
Expand Down
78 changes: 78 additions & 0 deletions test/test_add_var.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <boost/test/unit_test.hpp>

#include "scippp/model.hpp"

using namespace scippp;
using namespace std;

BOOST_AUTO_TEST_SUITE(AddVar)

// lb nullopt ub value lNuD
// lb nullopt ub nullopt lNuN
// lb value ub value GetSolVal
// lb value ub nullopt lDuN

const SCIP_Real LB_DEFAULT { 0.0 };
const SCIP_Real UB_DEFAULT { 1.0 };

BOOST_AUTO_TEST_CASE(lDuN, *boost::unit_test::tolerance(1e-3))
{
Model m1("Simple");
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, LB_DEFAULT, nullopt);
auto x2 = m1.addVar("x_2", 1);
m1.addConstr(x1 + x2 <= 1, "line");
m1.setObjsense(Sense::MINIMIZE);
m1.solve();
BOOST_REQUIRE(m1.getNSols() > 0);
BOOST_TEST(m1.getPrimalbound() == 0);

Model m2("Simple");
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, LB_DEFAULT, nullopt);
x2 = m2.addVar("x_2", 1);
m2.addConstr(x1 + x2 >= 1, "line");
m2.setObjsense(Sense::MAXIMIZE);
m2.solve();
BOOST_TEST(m2.getStatus() == SCIP_STATUS_UNBOUNDED);
}

BOOST_AUTO_TEST_CASE(lNuD, *boost::unit_test::tolerance(1e-3))
{
Model m1("Simple");
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, UB_DEFAULT);
auto x2 = m1.addVar("x_2", 1);
m1.addConstr(x1 + x2 <= 1, "line");
m1.setObjsense(Sense::MINIMIZE);
m1.solve();
BOOST_TEST(m1.getStatus() == SCIP_STATUS_UNBOUNDED);

Model m2("Simple");
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, UB_DEFAULT);
x2 = m2.addVar("x_2", 1);
m2.addConstr(x1 + x2 <= 1, "line");
m2.setObjsense(Sense::MAXIMIZE);
m2.solve();
BOOST_REQUIRE(m2.getNSols() > 0);
BOOST_TEST(m2.getPrimalbound() == 1);
}

BOOST_AUTO_TEST_CASE(lNuN, *boost::unit_test::tolerance(1e-3))
{
Model m1("Simple");
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, nullopt);
auto x2 = m1.addVar("x_2", 1);
m1.addConstr(x1 + x2 <= 1, "line");
m1.setObjsense(Sense::MINIMIZE);
m1.solve();
BOOST_TEST(m1.getStatus() == SCIP_STATUS_UNBOUNDED);

Model m2("Simple");
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, nullopt);
x2 = m2.addVar("x_2", 1);
m2.addConstr(x1 + x2 <= 1, "line");
m2.setObjsense(Sense::MAXIMIZE);
m2.solve();
BOOST_REQUIRE(m2.getNSols() > 0);
BOOST_TEST(m2.getPrimalbound() == 1);
}

BOOST_AUTO_TEST_SUITE_END()
1 change: 0 additions & 1 deletion test/test_var.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <boost/test/unit_test.hpp>

#include "scippp/model.hpp"
#include "scippp/parameters.hpp"

using namespace scippp;
using namespace std;
Expand Down