Skip to content

Commit c78e798

Browse files
authored
Merge pull request #3 from hedtke/make-upper-and-lower-bounds-optional
Make upper and lower bounds in addVar(s) optional
2 parents 6da1dd9 + 8c176f7 commit c78e798

File tree

4 files changed

+97
-14
lines changed

4 files changed

+97
-14
lines changed

include/scippp/model.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <algorithm>
44
#include <array>
55
#include <functional>
6+
#include <optional>
67
#include <scip/scip.h>
78
#include <string>
89
#include <type_traits>
@@ -86,16 +87,16 @@ class Model {
8687
* @param name of the variable when the model is written.
8788
* @param coeff Coefficient in the objective function.
8889
* @param varType variable type.
89-
* @param lb lower bound.
90-
* @param ub upper bound.
90+
* @param lb lower bound. \c std::nullopt is interpreted as -infinity.
91+
* @param ub upper bound. \c std::nullopt is interpreted as infinity.
9192
* @return Reference to the newly created variable.
9293
*/
9394
Var& addVar(
9495
const std::string& name,
9596
SCIP_Real coeff = 0.0,
9697
VarType varType = VarType::CONTINUOUS,
97-
SCIP_Real lb = 0.0,
98-
SCIP_Real ub = 1.0);
98+
std::optional<SCIP_Real> lb = 0.0,
99+
std::optional<SCIP_Real> ub = 1.0);
99100

100101
/**
101102
* Adds multiple variables to the model.
@@ -106,8 +107,8 @@ class Model {
106107
* @param numVars number of variables to create.
107108
* @param coeffs Object holding the coefficients for the objective function.
108109
* @param varType variable type.
109-
* @param lb lower bound.
110-
* @param ub upper bound.
110+
* @param lb lower bound. \c std::nullopt is interpreted as -infinity.
111+
* @param ub upper bound. \c std::nullopt is interpreted as infinity.
111112
* @return Vector of variables.
112113
*/
113114
template <typename CoeffType = ConstantCoefficient>
@@ -116,8 +117,8 @@ class Model {
116117
size_t numVars,
117118
const CoeffType& coeffs = COEFF_ZERO,
118119
VarType varType = VarType::CONTINUOUS,
119-
SCIP_Real lb = 0.0,
120-
SCIP_Real ub = 1.0)
120+
std::optional<SCIP_Real> lb = 0.0,
121+
std::optional<SCIP_Real> ub = 1.0)
121122
{
122123
std::vector<Var> result;
123124
result.reserve(numVars);
@@ -149,8 +150,8 @@ class Model {
149150
const std::string& prefix,
150151
const CoeffType& coeffs = COEFF_ZERO,
151152
VarType varType = VarType::CONTINUOUS,
152-
SCIP_Real lb = 0.0,
153-
SCIP_Real ub = 1.0)
153+
std::optional<SCIP_Real> lb = 0.0,
154+
std::optional<SCIP_Real> ub = 1.0)
154155
{
155156
std::array<Var, NumVars> result;
156157
auto vec { addVars(prefix, NumVars, coeffs, varType, lb, ub) };

source/model.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@
66

77
namespace scippp {
88

9-
Var& Model::addVar(const std::string& name, SCIP_Real coeff, VarType varType, SCIP_Real lb, SCIP_Real ub)
9+
Var& Model::addVar(
10+
const std::string& name,
11+
SCIP_Real coeff,
12+
VarType varType,
13+
std::optional<SCIP_Real> lb,
14+
std::optional<SCIP_Real> ub)
1015
{
1116
SCIP_VAR* var { nullptr };
1217
m_scipCallWrapper(SCIPcreateVarBasic(
1318
m_scip, /* SCIP environment */
1419
&var, /* reference to the variable */
1520
name.c_str(), /* name of the variable */
16-
lb, /* lower bound of the variable */
17-
ub, /* upper bound of the variable */
21+
lb != std::nullopt ? lb.value() : -SCIPinfinity(m_scip), /* lower bound of the variable */
22+
ub != std::nullopt ? ub.value() : SCIPinfinity(m_scip), /* upper bound of the variable */
1823
coeff, /* obj. coefficient. */
1924
static_cast<SCIP_Vartype>(varType) /* variable is binary */
2025
));

test/test_add_var.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include <boost/test/unit_test.hpp>
2+
3+
#include "scippp/model.hpp"
4+
5+
using namespace scippp;
6+
using namespace std;
7+
8+
BOOST_AUTO_TEST_SUITE(AddVar)
9+
10+
// lb nullopt ub value lNuD
11+
// lb nullopt ub nullopt lNuN
12+
// lb value ub value GetSolVal
13+
// lb value ub nullopt lDuN
14+
15+
const SCIP_Real LB_DEFAULT { 0.0 };
16+
const SCIP_Real UB_DEFAULT { 1.0 };
17+
18+
BOOST_AUTO_TEST_CASE(lDuN, *boost::unit_test::tolerance(1e-3))
19+
{
20+
Model m1("Simple");
21+
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, LB_DEFAULT, nullopt);
22+
auto x2 = m1.addVar("x_2", 1);
23+
m1.addConstr(x1 + x2 <= 1, "line");
24+
m1.setObjsense(Sense::MINIMIZE);
25+
m1.solve();
26+
BOOST_REQUIRE(m1.getNSols() > 0);
27+
BOOST_TEST(m1.getPrimalbound() == 0);
28+
29+
Model m2("Simple");
30+
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, LB_DEFAULT, nullopt);
31+
x2 = m2.addVar("x_2", 1);
32+
m2.addConstr(x1 + x2 >= 1, "line");
33+
m2.setObjsense(Sense::MAXIMIZE);
34+
m2.solve();
35+
BOOST_TEST(m2.getStatus() == SCIP_STATUS_UNBOUNDED);
36+
}
37+
38+
BOOST_AUTO_TEST_CASE(lNuD, *boost::unit_test::tolerance(1e-3))
39+
{
40+
Model m1("Simple");
41+
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, UB_DEFAULT);
42+
auto x2 = m1.addVar("x_2", 1);
43+
m1.addConstr(x1 + x2 <= 1, "line");
44+
m1.setObjsense(Sense::MINIMIZE);
45+
m1.solve();
46+
BOOST_TEST(m1.getStatus() == SCIP_STATUS_UNBOUNDED);
47+
48+
Model m2("Simple");
49+
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, UB_DEFAULT);
50+
x2 = m2.addVar("x_2", 1);
51+
m2.addConstr(x1 + x2 <= 1, "line");
52+
m2.setObjsense(Sense::MAXIMIZE);
53+
m2.solve();
54+
BOOST_REQUIRE(m2.getNSols() > 0);
55+
BOOST_TEST(m2.getPrimalbound() == 1);
56+
}
57+
58+
BOOST_AUTO_TEST_CASE(lNuN, *boost::unit_test::tolerance(1e-3))
59+
{
60+
Model m1("Simple");
61+
auto x1 = m1.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, nullopt);
62+
auto x2 = m1.addVar("x_2", 1);
63+
m1.addConstr(x1 + x2 <= 1, "line");
64+
m1.setObjsense(Sense::MINIMIZE);
65+
m1.solve();
66+
BOOST_TEST(m1.getStatus() == SCIP_STATUS_UNBOUNDED);
67+
68+
Model m2("Simple");
69+
x1 = m2.addVar("x_1", 1, VarType::CONTINUOUS, nullopt, nullopt);
70+
x2 = m2.addVar("x_2", 1);
71+
m2.addConstr(x1 + x2 <= 1, "line");
72+
m2.setObjsense(Sense::MAXIMIZE);
73+
m2.solve();
74+
BOOST_REQUIRE(m2.getNSols() > 0);
75+
BOOST_TEST(m2.getPrimalbound() == 1);
76+
}
77+
78+
BOOST_AUTO_TEST_SUITE_END()

test/test_var.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include <boost/test/unit_test.hpp>
22

33
#include "scippp/model.hpp"
4-
#include "scippp/parameters.hpp"
54

65
using namespace scippp;
76
using namespace std;

0 commit comments

Comments
 (0)