Scaffolding  0.1
This program can assemble genome scaffolds using the pairing information in paired-end reads.
degree_branching.hpp
1 
2 
3 #ifndef DEGREE_BRANCHING_HPP
4 #define DEGREE_BRANCHING_HPP
5 
6 #include <list>
7 
8 #include "utils/graph_typedefs.hpp"
9 #include "utils/scaffolding_typedefs.hpp"
10 #include "utils/instance.hpp"
11 #include "solv/trees.hpp"
12 #include "solv/branching.hpp"
13 
14 
15 namespace scaffold{
16  namespace solv{
17 
18 
19  // translate a branch using a translate map
20  template<class Graph>
21  void translate_branch(Branch<Graph>& branch, const VTranslateMap<Graph,Graph>& translate){
22  for(auto e = branch.edges.begin(); e != branch.edges.end();){
23  // Step 1: insert the translation of the edge b before e
24  e = branch.edges.emplace(e, std::make_pair(translate.at(e->first), translate.at(e->second)));
25  // Step 2: delete the original, advancing the iterator
26  e = branch.edges.erase(++e);
27  } // for
28  } // function
29 
30  // store all branches around v in a list
31  template<class Graph>
32  void get_branches_for_vertex(const Graph& g, const Vertex<Graph>& v, std::list<Branch<Graph> >& branches){
33  // for each edge uv incident to v, create the branch that takes uv
34  for(AdjIterRange<Graph> r = adjacent_vertices(v, g); r.first != r.second; ++r.first)
35  branches.push_back(Branch<Graph>(TakeBranch, std::make_pair(v, *r.first)));
36  }// function
37 
38  // apply a branch b to an instance H
39  template<class Graph>
40  void apply_branch(Instance<Graph>& I, const Branch<Graph>& b, DynProgSolution<>* const S = NULL){
41  switch(b.btype){
42  case DeleteBranch:
43  // the branch contains a list of edges to delete
44  I.delete_edges(b.edges, S);
45  break;
46  case TakeBranch:
47  // the branch contains a list of edges to take
48  for(auto e : b.edges) {
49  DEBUG4(std::cout << "taking edge "<<VertexPairAndGraph<Graph>(e, *I.g)<<std::endl);
50  // find the vertices matched with the extremities of e
51 /* const Vertex<Graph> x = I.matched_with(e.first);
52  const Vertex<Graph> y = I.matched_with(e.second);
53  //std::cout << "matched with "<<VertexAndGraph<Graph>(x, *I.g)<<" and "<<VertexAndGraph<Graph>(y, *I.g)<<std::endl;
54  // TODO: take note of the edges we replaced and: if xy is not an edge, then insert a new matching edge between x & y with the weight of the 3-path
55  if(!edge(x, y, *I.g).second){
56  //std::cout << VertexPairAndGraph<Graph>(std::make_pair(x,y), *I.g) << " doesn't exists"<<std::endl;
57  const size_t new_weight = I.weight_of(e.first, e.second)+I.weight_of(e.first, x)+I.weight_of(e.second, y);
58  // clear the vertices of e
59  I.clear_vertex(e.first);
60  I.clear_vertex(e.second);
61  // add the new matching edge
62  I.add_matching_edge(x, y, new_weight);
63  } else {
64 */
65  // remove all around e.first and e.second except for e and the 2 matching edges incident to them
66  I.clear_vertex_except(e.first, e.second, S);
67  I.clear_vertex_except(e.second, e.first, S);
68 // } // if
69  } // for
70  break;
71  } // switch
72  } // function
73 
74  // copy a given instance and apply the given branch to the copy
75  template<class Graph>
76  Instance<Graph>* copy_and_apply_branch(const Instance<Graph>& I, Branch<Graph>& b, DynProgSolution<>* const S = NULL){
77  // Step 1: make a copy H of I, but don't update infos, as we will invalidate it anyways by deleting edges
78  VTranslateMap<Graph,Graph> translate;
79  Instance<Graph>* H = new Instance<Graph>(I, &translate, false);
80  // Step 2: translate branch
81  translate_branch(b, translate);
82  // Step 3: apply the branch
83  apply_branch(*H, b, S);
84  // Step 4: update H's infos
85  H->infos.update_all();
86  return H;
87  }
88 
89 
90  // recursively transform I into a solution, TODO: add upper and lower bounds
91  template<class Graph>
92  void deg_solve_recursively(Instance<Graph>& I, DynProgSolution<>*& S, size_t depth = 0){
93  // Step 0: check for connected components
94  Instance<Graph> *J = I.split_off_component();
95  if(J){
96  // Step 1c: if a component has been split off, then recurse for the split-off instance
97  DEBUG3(std::cout << "splitting into components of size "<<num_vertices(*I.g)<<" and "<<num_vertices(*J->g)<<" (at "<<J<<")"<<std::endl);
98  DynProgSolution<>* solJ = new DynProgSolution<>(*J);
99  deg_solve_recursively(I, S, depth + 1);
100  deg_solve_recursively(*J, solJ, depth + 1);
101  delete J;
102 
103  DEBUG3(std::cout << "depth "<<depth<<": rejoining solutions for components"<<std::endl);
104 
105  if(!S->no_solutions() && !solJ->no_solutions()){
106  // if both components have solutions, unite them and find a solution subset
107  S->combine_disjoint_union(*solJ);
108  delete solJ;
109  return;
110  } else {
111  // if either component does not have a solution, return failure
112  S->invalidate();
113  delete solJ;
114  return;
115  }
116  }
117  // Step 1: base cases
118  DEBUG3(std::cout << "depth "<< depth<<": solving instance with " << num_vertices(*I.g) << " vertices:" << std::endl);
119  DEBUG5(write_adj_list_graph(std::cout, *I.g); std::cout << std::endl);
120  if(I.max_deg_two()) {
121  DEBUG3(std::cout << "it's already max-deg 2, getting all sub-solutions"<<std::endl);
122  get_all_solutions(I, S);
123  return;
124  }
125  if(I.is_acyclic()){
126  DEBUG3(std::cout << "it's a tree, getting all sub-solutions"<<std::endl);
127  solve_on_tree(I, S);
128  return;
129  }
130  // Step 2: preprocess
131  // Step 3: find a good branching
132  // Step 3a: get the maximum degree vertex v in I.g
133  const VertexAndDegree<Graph> vd = get_max_degree(*I.g);
134  const Vertex<Graph>& v = vd.first;
135  DEBUG4(std::cout << "branching on vertex: "<< VertexAndGraph<Graph>(v, *I.g)<<std::endl);
136  // Step 2b: get all branches for v
137  std::list<Branch<Graph> > branches;
138  get_branches_for_vertex(*I.g, v, branches);
139 
140  // Step 3: for each branch, make a copy of I, apply the branching, and recurse
141  DynProgSolution<> max_sol(I);
142  for(Branch<Graph> b : branches){
143  DEBUG3(std::cout << "depth "<<depth<<":"<<std::endl<<" branching: "<< BranchAndGraph<Graph>(b, *I.g)<<std::endl);
144  // Step 3a: get a copy H of I to which the branch has been applied
145  DynProgSolution<>* solH = new DynProgSolution<>(I);
146  Instance<Graph>* H = copy_and_apply_branch(I, b, solH);
147  // Step 3b: recurse
148  deg_solve_recursively(*H, solH, depth + 1);
149  DEBUG4(std::cout << "depth "<<depth<<": returned with solution"<<std::endl);
150  delete H;
151  // update solution
152  if(!solH->no_solutions()) max_sol.combine_min_of_two(*solH);
153  delete solH;
154  }// for
155  if(max_sol.no_solutions()) S->invalidate(); else S->destructive_append(max_sol);
156  DEBUG3(std::cout << "returning from depth "<<depth<<" with "; if(S->no_solutions()) std::cout << "no solutions"<<std::endl; else std::cout << "solutions: "<<*S<<std::endl;);
157  } // function
158 
159  /*
160  // create a list of graphs yielded by branching over high degree vertices, or an empty list if all degrees are 0
161  template<class Graph>
162  std::list<Graph*> deg_branch(const Graph& g){
163  // Step 1: find the highest degree vertex
164  const VertexAndDegree<Graph> vd = get_max_degree(g);
165  // Step 2: if the maximum degree is greater than 0, then branch on this vertex; otherwise, return an empty graphlist
166  if(vd.second > 2)
167  return deg_branch_on_vertex(g, vd.first);
168  else
169  return std::list<Graph*>();
170  }// function
171  */
172 
173  } // namespace
174 } // namespace
175 
176 #endif
Definition: read_adj_list.hpp:22