1 /* MIP_Problem class implementation: non-inline template functions.
2    Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3    Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #ifndef PPL_MIP_Problem_templates_hh
25 #define PPL_MIP_Problem_templates_hh 1
26 
27 #include "Variables_Set_defs.hh"
28 
29 namespace Parma_Polyhedra_Library {
30 
31 template <typename In>
MIP_Problem(const dimension_type dim,In first,In last,const Variables_Set & int_vars,const Linear_Expression & obj,const Optimization_Mode mode)32 MIP_Problem::MIP_Problem(const dimension_type dim,
33                          In first, In last,
34                          const Variables_Set& int_vars,
35                          const Linear_Expression& obj,
36                          const Optimization_Mode mode)
37   : external_space_dim(dim),
38     internal_space_dim(0),
39     tableau(),
40     working_cost(0),
41     mapping(),
42     base(),
43     status(PARTIALLY_SATISFIABLE),
44     pricing(PRICING_STEEPEST_EDGE_FLOAT),
45     initialized(false),
46     input_cs(),
47     inherited_constraints(0),
48     first_pending_constraint(0),
49     input_obj_function(obj),
50     opt_mode(mode),
51     last_generator(point()),
52     i_variables(int_vars) {
53   // Check that integer Variables_Set does not exceed the space dimension
54   // of the problem.
55   if (i_variables.space_dimension() > external_space_dim) {
56     std::ostringstream s;
57     s << "PPL::MIP_Problem::MIP_Problem"
58       << "(dim, first, last, int_vars, obj, mode):\n"
59       << "dim == "<< external_space_dim << " and int_vars.space_dimension() =="
60       << " " << i_variables.space_dimension() << " are dimension"
61       "incompatible.";
62     throw std::invalid_argument(s.str());
63   }
64 
65   // Check for space dimension overflow.
66   if (dim > max_space_dimension()) {
67     throw std::length_error("PPL::MIP_Problem:: MIP_Problem(dim, first, "
68                             "last, int_vars, obj, mode):\n"
69                             "dim exceeds the maximum allowed"
70                             "space dimension.");
71   }
72   // Check the objective function.
73   if (obj.space_dimension() > dim) {
74     std::ostringstream s;
75     s << "PPL::MIP_Problem::MIP_Problem(dim, first, last,"
76       << "int_vars, obj, mode):\n"
77       << "obj.space_dimension() == "<< obj.space_dimension()
78       << " exceeds d == "<< dim << ".";
79     throw std::invalid_argument(s.str());
80   }
81   // Check the constraints.
82   try {
83     for (In i = first; i != last; ++i) {
84       if (i->is_strict_inequality()) {
85         throw std::invalid_argument("PPL::MIP_Problem::"
86                                     "MIP_Problem(dim, first, last, int_vars,"
87                                     "obj, mode):\nrange [first, last) contains"
88                                     "a strict inequality constraint.");
89       }
90       if (i->space_dimension() > dim) {
91         std::ostringstream s;
92         s << "PPL::MIP_Problem::"
93           << "MIP_Problem(dim, first, last, int_vars, obj, mode):\n"
94           << "range [first, last) contains a constraint having space"
95           << "dimension  == " << i->space_dimension() << " that exceeds"
96           "this->space_dimension == " << dim << ".";
97         throw std::invalid_argument(s.str());
98       }
99       add_constraint_helper(*i);
100     }
101   } catch (...) {
102     // Delete the allocated constraints, to avoid memory leaks.
103 
104     for (Constraint_Sequence::const_iterator
105           i = input_cs.begin(), i_end = input_cs.end();
106           i != i_end; ++i) {
107       delete *i;
108     }
109 
110     throw;
111   }
112   PPL_ASSERT(OK());
113 }
114 
115 template <typename In>
MIP_Problem(dimension_type dim,In first,In last,const Linear_Expression & obj,Optimization_Mode mode)116 MIP_Problem::MIP_Problem(dimension_type dim,
117                          In first, In last,
118                          const Linear_Expression& obj,
119                          Optimization_Mode mode)
120   : external_space_dim(dim),
121     internal_space_dim(0),
122     tableau(),
123     working_cost(0),
124     mapping(),
125     base(),
126     status(PARTIALLY_SATISFIABLE),
127     pricing(PRICING_STEEPEST_EDGE_FLOAT),
128     initialized(false),
129     input_cs(),
130     inherited_constraints(0),
131     first_pending_constraint(0),
132     input_obj_function(obj),
133     opt_mode(mode),
134     last_generator(point()),
135     i_variables() {
136   // Check for space dimension overflow.
137   if (dim > max_space_dimension()) {
138     throw std::length_error("PPL::MIP_Problem::"
139                             "MIP_Problem(dim, first, last, obj, mode):\n"
140                             "dim exceeds the maximum allowed space "
141                             "dimension.");
142   }
143   // Check the objective function.
144   if (obj.space_dimension() > dim) {
145     std::ostringstream s;
146     s << "PPL::MIP_Problem::MIP_Problem(dim, first, last,"
147       << " obj, mode):\n"
148       << "obj.space_dimension() == "<< obj.space_dimension()
149       << " exceeds d == "<< dim << ".";
150     throw std::invalid_argument(s.str());
151   }
152   // Check the constraints.
153   try {
154     for (In i = first; i != last; ++i) {
155       if (i->is_strict_inequality()) {
156         throw std::invalid_argument("PPL::MIP_Problem::"
157                                     "MIP_Problem(dim, first, last, obj, mode):"
158                                     "\n"
159                                     "range [first, last) contains a strict "
160                                     "inequality constraint.");
161       }
162       if (i->space_dimension() > dim) {
163         std::ostringstream s;
164         s << "PPL::MIP_Problem::"
165           << "MIP_Problem(dim, first, last, obj, mode):\n"
166           << "range [first, last) contains a constraint having space"
167           << "dimension" << " == " << i->space_dimension() << " that exceeds"
168           "this->space_dimension == " << dim << ".";
169         throw std::invalid_argument(s.str());
170       }
171       add_constraint_helper(*i);
172     }
173   } catch (...) {
174     // Delete the allocated constraints, to avoid memory leaks.
175 
176     for (Constraint_Sequence::const_iterator
177           i = input_cs.begin(), i_end = input_cs.end();
178           i != i_end; ++i) {
179       delete *i;
180     }
181 
182     throw;
183   }
184   PPL_ASSERT(OK());
185 }
186 
187 } // namespace Parma_Polyhedra_Library
188 
189 #endif // !defined(PPL_MIP_Problem_templates_hh)
190