6 #include "utils/dp_solution.hpp"
10 namespace scaffold{
namespace solv {
namespace trees {
15 Edge<Graph>* get_edge_to_first_unvisited_neighbor(
const Vertex<Graph>& u,
const unordered_set<Vertex<Graph> >& visited,
const Graph& g)
17 for(OEdgeIterRange<Graph> r = out_edges(u, g); r.first != r.second; ++r.first)
18 if(!
contains(visited, target(*r.first, g)))
19 return new Edge<Graph>(*r.first);
25 template<
class Compare = std::less<
size_t> >
34 const size_t max_paths;
38 TreeDPinfos(
const size_t _max_paths): table(
new entries_t(1, _max_paths)), childs_done(0), max_paths(_max_paths), seen_matching(
false) {
39 table->put_empty(IndexType(0,0));
44 void combine_with_child(
const TreeDPinfos& child,
const bool is_matching_edge,
const EdgeName& uv,
const size_t uv_weight){
45 entries_t *result =
new entries_t(table->max);
46 for(
auto E_i = table->get_entries(); E_i.first != E_i.second; ++E_i.first){
47 const auto& E = *E_i.first;
48 const IndexType ap = E.first;
49 for(
auto cE_i = child.table->get_entries(); cE_i.first != cE_i.second; ++cE_i.first){
50 const auto& cE = *cE_i.first;
51 const IndexType cap = cE.first;
52 DEBUG5(std::cout <<
"combining index ("<<(
int)ap.c<<
","<<ap.p<<
") with ("<<(
int)cap.c<<
","<<cap.p<<
") and the matching flag is "<<is_matching_edge<<
" weight: "<<uv_weight<<std::endl);
55 assert(cap.c <= cap.p);
60 const size_t sum_p = 1 + (ap.p - ap.c) + (cap.p - cap.c);
61 if(sum_p <= max_paths) result->put(IndexType(sum_p, ap.c), *E.second, *cE.second);
65 if((ap.c == 0) && (cap.c == 0)){
67 const size_t sum_p = ap.p + cap.p - (seen_matching ? 1 : 0);
68 if(sum_p <= max_paths) {
74 ME->weight += uv_weight;
76 if(!result->put(IndexType(sum_p, 1), ME))
delete ME;
80 const size_t sum_p = ap.p + cap.p;
81 if(sum_p <= max_paths){
87 ME->weight += uv_weight;
89 if(!result->put(IndexType(sum_p, ap.c), ME))
delete ME;
99 friend std::ostream& operator<<(std::ostream& os,
const TreeDPinfos& infos){
101 for(
size_t p = 0; p <= infos.max_paths; ++p){
103 try{ os << infos.table->at(IndexType(p,0)).weight <<
"\t"; }
catch(...) { os <<
"\t"; };
104 try{ os << infos.table->at(IndexType(p,1)).weight <<
"\t"; }
catch(...) { os <<
"\t"; };
114 template<
class Graph,
class Compare = std::less<
size_t> >
116 DEBUG4(std::cout <<
"initializing leaves"<<std::endl);
117 for(VertexIterRange<Graph> r = vertices(*I.g); r.first != r.second; ++r.first)
118 if(degree(*r.first, *I.g) == 1){
120 DPmap.emplace(std::piecewise_construct, std::make_tuple(*r.first), std::make_tuple(I.
num_paths));
121 leaves.push(*r.first);
123 DEBUG4(std::cout <<
"initialized "<<leaves.size()<<
" leaves"<<std::endl);
127 template<
class Graph,
class Compare = std::less<
size_t> >
128 void solve_on_tree(
Instance<Graph>& I, DynProgSolution<Compare>*
const S){
129 assert(I.is_acyclic());
131 unordered_map<Vertex<Graph>, TreeDPinfos<Compare> > DPmap;
132 unordered_set<Vertex<Graph> > visited;
135 std::queue<Vertex<Graph> > leaves;
136 init_leaves(I, leaves, DPmap);
140 typename unordered_map<Vertex<Graph>, TreeDPinfos<Compare> >::const_iterator u_infos;
141 while(!leaves.empty()){
142 DEBUG4(std::cout <<
"queue has "<<leaves.size()<<
" items, next one is "<<VertexAndGraph<Graph>(leaves.front(), *I.g)<<std::endl);
143 u = leaves.front(); leaves.pop();
145 u_infos = DPmap.find(u);
146 assert(u_infos != DPmap.end());
147 DEBUG4(std::cout <<
"with DP entry: "<<std::endl<<u_infos->second<<std::endl);
149 Edge<Graph>* to_parent = get_edge_to_first_unvisited_neighbor(u, visited, *I.g);
151 if(!to_parent)
break;
152 const Vertex<Graph> parent = target(*to_parent, *I.g);
155 const bool is_matching_edge = (I.matched.at(u) == parent);
156 const EdgeName uv_name = std::make_pair(
get(vertex_name, *I.g, u),
get(vertex_name, *I.g, parent));
157 const size_t uv_weight =
get(edge_weight, *I.g, *to_parent);
159 TreeDPinfos<Compare>& p_infos = DPmap.emplace(parent, I.
num_paths).first->second;
161 p_infos.combine_with_child(u_infos->second, is_matching_edge, uv_name, uv_weight);
162 p_infos.childs_done++;
164 if(p_infos.childs_done == degree(parent, *I.g) - 1) leaves.push(parent);
167 DPmap.erase(u_infos);
171 for(
auto E = u_infos->second.table->get_entries(); E.first != E.second; ++E.first)
Definition: graph_utils.hpp:18
Definition: min_matrix.hpp:191
Definition: read_adj_list.hpp:22
unsigned num_paths
max number of paths in solutions
Definition: instance.hpp:32
bool contains(const Set &s, const Element &el)
a more readable containment check
Definition: utils.hpp:171
Definition: min_matrix.hpp:36
Definition: graph_typedefs.hpp:26