Scaffolding  0.1
This program can assemble genome scaffolds using the pairing information in paired-end reads.
ilp_common.hpp
1 #ifndef ILP_COMMON_HPP
2 #define ILP_COMMON_HPP
3 
4 
5 #define is_true(x) (lround(x))
6 
7 // if LAZY_ADD_ALL_CYCLES is defined, then all cycles in the solution returned by CPLEX are added by the lazy callback
8 // otherwise, just the first cycle is added
9 #define LAZY_ADD_ALL_CYCLES
10 
11 #include <iostream>
12 #include <sstream>
13 #include <boost/bimap.hpp>
14 #include <boost/bimap/unordered_set_of.hpp>
15 
16 #include <ilcplex/ilocplex.h>
17 
18 #include "utils/utils.hpp"
19 #include "utils/graph_typedefs.hpp"
20 
21 
22 
23 namespace scaffold { namespace solv { namespace ilp {
24 
25  struct ilp_options {
26  // set the following to false to allow contig jumps in the solution
27  bool ignore_contig_jumps;
28 
29  // set the following to false to gain the weight each time an edge is used in the solution
30  bool multi_take_all;
31 
32  ilp_options(bool _ignore_contig_jumps = true,
33  bool _multi_take_all = true
34  ):
35  ignore_contig_jumps(_ignore_contig_jumps),
36  multi_take_all(_multi_take_all)
37  {}
38  };
39 
41  unsigned cuts_added;
42  unsigned times_called;
43  double root_relax;
44  timer time_spent;
45 
46  callback_statistics(): cuts_added(0), times_called(0) {};
47  };
48 
49 
50  // a mapping of vertices to variables
51  using VertexVarMap = boost::unordered_map<ScafVertex, IloNumVar>;
52  using VertexVarIter = typename VertexVarMap::iterator;
53  using VertexAndVar = typename VertexVarMap::value_type;
54 
55  // a mapping of vertices to expressions
56  using VertexExpMap = boost::unordered_map<ScafVertex, IloExpr>;
57  using VertexExpIter = typename VertexExpMap::iterator;
58  using VertexAndExp = typename VertexExpMap::value_type;
59 
60  // a mapping of edges to variables
61  using EdgeVarMap = boost::unordered_map<ScafVertexPair, IloNumVar>;
62  using EdgeVarIter = typename EdgeVarMap::iterator;
63  using EdgeVarCIter = typename EdgeVarMap::const_iterator;
64  using EdgeAndVar = typename EdgeVarMap::value_type;
65 
66  // a mapping of edges to expressions
67  using EdgeExpMap = boost::unordered_map<ScafVertexPair, IloExpr>;
68  using EdgeExpIter = typename EdgeExpMap::iterator;
69  using EdgeExpCIter = typename EdgeExpMap::const_iterator;
70  using EdgeAndExp = typename EdgeExpMap::value_type;
71 
72  // a contig-jump network manages contigs that can be jumped by reads due to their small length
73  // each directed edge uv is assigned an EdgeVarMap for each time it might occur in the solution (multiplicity of uv)
74  using ContigJumpVars = boost::unordered_map<ScafVertexPair, std::list<EdgeVarMap> >;
75 
76 
78  const Instance& I;
79  EdgeVarMap times_used_undir;
80  VertexVarMap from_source, to_path_sink, to_cycle_sink;
81 
82  var_collection_virt(const Instance& _I): I(_I) {}
83  };
84 
86  using var_collection_virt::var_collection_virt;
87  EdgeVarMap times_used;
88  EdgeVarMap used_at_all;
89  EdgeVarMap contig_jumps;
90  };
91 
92 
93 
94  // auxiliary graph for callback construction
95  template<typename VertexProp = no_property, typename EdgeProp = no_property>
96  using AuxiliaryGraph = adjacency_list<hash_setS,
97  listS,
98  bidirectionalS,
99  VertexProp,
100  EdgeProp
101  >;
102 
103 
104  template<class GraphA, class GraphB>
105  using TranslateBiMap = boost::bimap< boost::bimaps::unordered_set_of<Vertex<GraphA> >, boost::bimaps::unordered_set_of<Vertex<GraphB> > >;
106 
107  // find root LP relaxation as SOLVECallback
108  class RelaxCallback: public IloCplex::SolveCallbackI{
109  callback_statistics& stats;
110  bool root;
111  public:
112 
113  IloCplex::CallbackI* duplicateCallback() const{
114  return (new (getEnv()) RelaxCallback(getEnv(), stats));
115  }
116 
117  RelaxCallback(IloEnv env, callback_statistics& _stats):
118  IloCplex::SolveCallbackI(env),
119  stats(_stats),
120  root(false)
121  {}
122 
123  void main(){
124  if(!root){
125  std::cout<<"Relaxation solution in root has value "<<getBestObjValue()<<std::endl;
126  stats.root_relax = getBestObjValue();
127  root = true;
128  //masteropt = getObjValue();
129  }
130  }
131  };
132  IloCplex::Callback GetRelaxCallback(IloEnv env, callback_statistics& stats){
133  return (new (env) RelaxCallback(env, stats));
134  }
135 
136 
137  // print variables set to true in a mapping something->variables, print the prefix only if there are true variables
138  void print_true_map_vars(const IloCplex& cplex,
139  const Instance& I,
140  const EdgeVarMap& vars,
141  const std::string& prefix = "",
142  std::ostream& os = std::cout)
143  {
144  bool is_empty = true;
145  for(const auto& v_pair: vars)
146  if(is_true(cplex.getValue(v_pair.second))){
147  if(is_empty){
148  is_empty = false;
149  os << prefix;
150  }
151  os << " "<< I.get_edge_name(v_pair.first);
152  }
153  if(!is_empty) os << std::endl;
154  }
155 
156 
157  // print contig jumps from a ContigJumpMap
158  void print_contig_jumps(const IloCplex& cplex,
159  const var_collection_multi& vars,
160  std::ostream& os = std::cout)
161  {
162  print_true_map_vars(cplex, vars.I, vars.contig_jumps, "", os);
163  }
164 
165  // add a scaled variable to the expression at u in a Vertex-Expression Map
166  void add_to_VExpr(const IloEnv& env,
167  VertexExpMap& expr_map,
168  const ScafVertex& u,
169  const IloNumVar& x,
170  const double scale)
171  {
172  expr_map.DEEP_EMPLACE(u, env).first->second += (x * scale);
173  }
174 
175 
176 
177 
178 }}}// namespace
179 
180 
181 #endif
Definition: ilp_common.hpp:85
Definition: read_adj_list.hpp:22
a simple timer class that can be paused and resumed
Definition: profiling.hpp:23
an instance is a ScaffoldGraph with given path- & cycle- numbers and a solution to keep track of dele...
Definition: instance.hpp:27
Definition: ilp_common.hpp:108
EdgeName get_edge_name(const VertexPair< Graph > &uv) const
get a copy of the name of the edge uv; independent of its presence
Definition: scaffold_graph.hpp:421
Definition: ilp_common.hpp:25
Definition: ilp_common.hpp:40
Definition: ilp_common.hpp:77