TCPSPSuite
obilp.hpp
1 #ifndef ILP_OBILP_HPP
2 #define ILP_OBILP_HPP
3 
4 #include "../manager/solvers.hpp" // for get_free_N
5 #include "../util/log.hpp" // for Log
6 #include "generated_config.hpp" // for GUROBI_FOUND
7 #include "ilp.hpp" // for ILPBase
8 
9 #include <string> // for string
10 #include <vector> // for vector
11 class AdditionalResultStorage;
12 class Instance;
13 class SolverConfig;
14 namespace solvers {
15 template <unsigned int>
16 struct registry_hook;
17 }
18 
19 #if defined(GUROBI_FOUND)
20 #include "../contrib/ilpabstraction/src/ilpa_gurobi.hpp"
21 #endif
22 
23 #if defined(CPLEX_FOUND)
24 #include "../contrib/ilpabstraction/src/ilpa_cplex.hpp"
25 #endif
26 
27 template <class SolverT>
28 class OBILP : public ILPBase<SolverT> {
29 public:
30  OBILP(const Instance & instance, AdditionalResultStorage & additional,
31  const SolverConfig & sconf);
32 
33  void run();
34  static std::string get_id();
35 
36 private:
37  Log l;
38 
39  using Base = ILPBase<SolverT>;
40  using MIPSolver = typename Base::MIPSolver;
41  using Model = typename Base::Model;
42  using Variable = typename Base::Variable;
43  using Expression = typename Base::Expression;
44  using VarType = typename Base::VarType;
45  using ParamType = typename Base::ParamType;
46  using ModelStatus = typename Base::ModelStatus;
47  using Constraint = typename Base::Constraint;
48 
49  /*
50  * Data to perform things that are only relevant for overlapping jobs only
51  * on them.
52  */
53  struct Event
54  {
55  unsigned int jid;
56  unsigned int time;
57  bool start;
58  };
59  std::vector<Event> events;
60  std::vector<unsigned int> earliest_starts;
61  std::vector<unsigned int> latest_finishs;
62  void generate_events() noexcept;
63 
64  // TODO rename in 'disjunct' and 'order'?
65  /*
66  * These are the D_{i,j} variables from the paper, meaning "Job j completely
67  * after job i".
68  *
69  * after_vars[i][j] must be zero if j does not start after i finishes.
70  */
71  std::vector<std::unordered_map<unsigned int, Variable>> disjunct_vars;
72 
73  /*
74  * These are the O_{i,j} variables from the paper, meaning "Job i
75  * starts before (or at the same time as) job j"
76  *
77  * before_vars[i][j] must be 1 if the start time of i is less or equal
78  * than the start time of j.
79  */
80  std::vector<std::unordered_map<unsigned int, Variable>> order_vars;
81 
82  /*
83  * Usage expressions.
84  *
85  * start_usage[rid][j] is lower-bounded by the amount of resource <rid>
86  * that is at the moment in which job j is started.
87  */
88  std::vector<std::vector<Expression>> start_usage;
89 
90  // TODO FIXME DEBUG ONLY
91  std::vector<std::vector<Variable>> start_usage_var;
92  std::vector<Constraint> usage_constraints;
93 
94  void prepare_variables();
95 
96  /* Force after_vars to 0 where applicable */
97  void prepare_after_constraints();
98 
99  /* Force before_vars to 1 where applicable */
100  void prepare_before_constraints();
101 
102  /* Create start_usage expressions, include them in the objective */
103  void prepare_start_usage_exprs();
104 
105  void prepare();
106 };
107 
108 // Register the solver
109 namespace solvers {
110 #if defined(GUROBI_FOUND)
111 template <>
112 struct registry_hook<
113  solvers::get_free_N<OBILP<ilpabstraction::GurobiInterface>>()>
114 {
115  constexpr static unsigned int my_N =
116  solvers::get_free_N<OBILP<ilpabstraction::GurobiInterface>>();
117 
118  auto
119  operator()()
120  {
121  return solvers::register_class<OBILP<ilpabstraction::GurobiInterface>,
122  my_N>{}();
123  }
124 };
125 #endif
126 
127 #if defined(CPLEX_FOUND)
128 template <>
129 struct registry_hook<
130  solvers::get_free_N<OBILP<ilpabstraction::CPLEXInterface>>()>
131 {
132  constexpr static unsigned int my_N =
133  solvers::get_free_N<OBILP<ilpabstraction::CPLEXInterface>>();
134 
135  auto
136  operator()()
137  {
138  return solvers::register_class<OBILP<ilpabstraction::CPLEXInterface>,
139  my_N>{}();
140  }
141 };
142 #endif
143 } // namespace solvers
144 
145 #endif /* ILP_OBILP_HPP */
Instance
a TCPSP instance
Definition: instance.hpp:24