8 #include <boost/graph/subgraph.hpp>
10 #include "TOL/GreedyFillIn.h"
11 #include "TOL/TreeDecomposition.h"
14 #include "utils/graph_typedefs.hpp"
18 #include "utils/td_subgraph.hpp"
19 #include "utils/scaffolding_utils.hpp"
22 #include "preprocess/pp_pendant_match.hpp"
23 #include "solv/dp_table.hpp"
24 #include "solv/trees.hpp"
26 using namespace boost;
28 namespace scaffold{
namespace solv {
namespace DP{
30 using scaffold::operator<<;
34 TOL::TreeDecomposition* get_tree_decomp(
const Graph& g, TOL::VTranslateBoostTOL<Graph>* vtranslate = NULL)
37 TOL::Graph TOLg(0, num_vertices(g));
38 convert(g, TOLg, vtranslate);
40 TOL::EliminationOrdering eo(TOLg);
41 TOL::GreedyFillIn gfi(eo);
44 return new TOL::TreeDecomposition(TOLg, eo);
52 void DP_treat_edge(DP_Table<Graph>& child_table, DP_Table<Graph>& parent_table, EdgeSet<Graph>& already_introduced,
const Graph& g)
54 DEBUG2(std::cout <<
"treating edge from child with bag ";
55 for(
auto& i: child_table.index->left) std::cout << VertexAndGraph<Graph>(i.first, g)<<
" ";
56 std::cout <<
" to parent with bag ";
57 for(
auto& i: parent_table.index->left) std::cout << VertexAndGraph<Graph>(i.first, g)<<
" ";
58 std::cout << std::endl);
60 VertexSet<Graph> to_forget;
61 for(
auto& vi: child_table.index->left){
62 const Vertex<Graph> v = vi.first;
63 const auto& parent_vset = parent_table.index->left;
64 if(!
contains(parent_vset, v)) to_forget.emplace(v);
68 for(
const Vertex<Graph>& v : to_forget){
69 DEBUG3(std::cout <<
"introducing edges incident with "<<VertexAndGraph<Graph>(v, g)<<
":"<<std::endl);
70 for(OEdgeIterRange<Graph> r = out_edges(v, g); r.first != r.second; ++r.first)
72 if(!
contains(already_introduced, *r.first) && (
contains(child_table.index->left, target(*r.first, g)))){
73 child_table.intro_edge(*r.first);
74 already_introduced.insert(*r.first);
75 already_introduced.insert(edge(target(*r.first, g), source(*r.first, g), g).first);
80 child_table.forget_vertices(to_forget);
83 VertexSet<Graph> to_introduce;
84 for(
auto& vi: parent_table.index->left){
85 const Vertex<Graph> v = vi.first;
86 const auto& child_vset = child_table.index->left;
87 if(!
contains(child_vset, v)) to_introduce.emplace(v);
89 child_table.intro_vertices(to_introduce);
92 DEBUG3(std::cout <<
"joining tables..."<<std::endl);
93 parent_table.join(child_table);
95 DEBUG5(std::cout <<
"final table of parent:"<<std::endl<<parent_table<<std::endl);
98 size_t size = parent_table.size();
99 if(size > 1000000) std::cout <<
"table size: "<<parent_table.size()<<
" entries"<<std::endl;
105 template<
class Graph,
class Compare = std::less<size_t> >
108 const Compare is_better;
111 return is_better(num_vertices(*I1->g), num_vertices(*I2->g));
116 template<
class Graph>
119 DEBUG3(std::cout <<
"running preprocessing..."<< std::endl);
120 preprocess::pp_matching_pendant(I);
121 DEBUG3(std::cout <<
"after preprocessing: "<<boost::num_vertices(*I.g)<<
" vertices & "<<boost::num_edges(*I.g)<<
" edges"<<std::endl);
126 if(J) components.push(J);
else break;
128 DEBUG3(std::cout <<
"split off "<<components.size()<<
" connected components for independent solving"<< std::endl);
129 if(!components.empty()){
132 DEBUG2(std::cout <<
"instance has "<<components.size()<<
" components"<<std::endl);
138 while(!components.empty()){
143 DEBUG3(std::cout <<
"next component has "<<num_vertices(*J->g)<<
" vertices & we're looking for "<<J->
num_paths<<
" paths & "<<J->
num_cycles<<
" cycles"<<std::endl);
145 DynProgSolution<std::greater<size_t> > solJ(*J);
148 if(J != &I)
delete J;
150 if(!solJ.no_solutions()){
151 DEBUG4(std::cout <<
" joining solution" << solJ<<std::endl);
152 S.combine_disjoint_union(solJ);
154 used_up = S.smallest_index();
155 DEBUG4(std::cout <<
" S now has "<<S.size()<<
" entries, using up "<<used_up<<
" paths & cycles "<<std::endl);
165 if(I.max_deg_two()) {
166 DEBUG3(std::cout <<
"it's max-deg 2"<<std::endl);
167 treat_deg_two(I, &S);
171 DEBUG3(std::cout <<
"it's a tree"<<std::endl);
172 solve_on_tree(I, &S);
178 TOL::VTranslateBoostTOL<Graph>* vtranslate =
new TOL::VTranslateBoostTOL<Graph>();
179 const TOL::TreeDecomposition *TD = get_tree_decomp(*I.g, vtranslate);
180 const TOL::Tree t(TD->tree());
181 DEBUG2(std::cout <<
"using tree decomposition of width "<<TD->width()<<std::endl);
184 std::stack<std::pair<std::pair<TOL::Tree::const_child_iterator, TOL::Tree::const_child_iterator>, DP_Table<Graph>*> > child_stack;
186 unordered_set<TOL::Tree::Node> visited;
188 EdgeSet<Graph> introduced_edges(default_buckets, *I.g);
191 const TOL::Tree::Node r = t.root();
192 assert(!t.is_leaf(r));
195 child_stack.emplace(std::make_pair(t.all_children(r),
new DP_Table<Graph>(I, TD->subset(r), vtranslate)));
198 const TOL::Tree::Node& u = *(child_stack.top().first.first);
202 child_stack.emplace(make_pair(t.all_children(u),
new DP_Table<Graph>(I, TD->subset(u), vtranslate)));
204 if(t.is_leaf(u)) child_stack.top().second->init_as_leaf();
208 std::cout <<
"adding to stack: "<<u<<
" with VSet:\t";
209 std::list<Vertex<Graph> > l;
210 child_stack.top().second->get_VSet(l);
211 std::cout << VertexListAndGraph<Graph>(l, *I.g)<<
"\t\t children: ";
212 for(
auto ra = child_stack.top().first.first; ra != child_stack.top().first.second; ++ra) std::cout << *ra<<
" ";
213 std::cout << std::endl;
216 }
else ++child_stack.top().first.first;
219 std::pair<TOL::Tree::const_child_iterator, TOL::Tree::const_child_iterator>& childs = child_stack.top().first;
220 if(childs.first == childs.second){
222 if(child_stack.size() > 1){
223 DP_Table<Graph>* child_table = child_stack.top().second;
225 DP_Table<Graph>* parent_table = child_stack.top().second;
227 DP_treat_edge(*child_table, *parent_table, introduced_edges, *I.g);
231 if(parent_table->empty()){
232 while(!child_stack.empty()){
233 DP_Table<Graph>* current_table = child_stack.top().second;
234 current_table->clear();
235 delete current_table;
246 DP_Table<Graph> root_table(I, VertexSet<Graph>());
247 DP_Table<Graph>* last_table = child_stack.top().second;
248 DP_treat_edge(*last_table, root_table, introduced_edges, *I.g);
250 root_table.read_solution(S);
Definition: tw_dp.hpp:106
Definition: graph_utils.hpp:18
Definition: read_adj_list.hpp:22
unsigned num_cycles
max number of cycles in solutions
Definition: instance.hpp:33
Definition: dp_solution.hpp:19
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: graph_typedefs.hpp:26