8 #include "utils/graph_typedefs.hpp"
12 namespace scaffold{
namespace solv{
namespace DP {
14 typedef std::bitset<MAX_TW> DegMap;
16 DegMap permute_degmap(
const DegMap& d,
const BytePermutation& perm)
19 for(byte i = 0; i < MAX_TW; ++i)
20 if(d.test(i)) result.set(perm[i]);
25 inline bool compatible(
const DegMap& d1,
const DegMap& M1,
const DegMap& d2,
const DegMap& M2){
26 return ((d1 ^ M1) & (d2 ^ M2)).none();
32 typedef PCMinMatrix<std::greater<size_t> > pc_to_sol;
42 PathsAndCycles modify_P_with_uv(PermissiveMatching& P,
const byte u_idx,
const byte du,
const byte v_idx,
const byte dv)
47 if((du == 1) && (dv == 1)){
49 assert(P[u_idx] == u_idx);
50 assert(P[v_idx] == v_idx);
56 if((du == 2) && (dv == 1)){
57 const byte x_idx = P[u_idx];
59 assert(x_idx != v_idx);
69 if((du == 2) && (dv == 2)){
71 const byte x_idx = P[u_idx];
72 const byte y_idx = P[v_idx];
78 assert(y_idx == u_idx);
83 if((x_idx == u_idx) && (y_idx != v_idx)) P[y_idx] = y_idx;
86 if((x_idx != u_idx) && (y_idx == v_idx)) P[x_idx] = x_idx;
89 if((x_idx != u_idx) && (x_idx != v_idx) && (y_idx != u_idx) && (y_idx != v_idx)){
95 if((x_idx == u_idx) && (y_idx == v_idx)){
102 DEBUG4(std::cout <<
"new P = "<<P<<
" and we closed "<<result<<
" paths and cycles"<<std::endl);
107 class P_to_pc_map :
public unordered_map<PermissiveMatching, pc_to_sol*>
110 using unordered_map<PermissiveMatching, pc_to_sol*>::iterator;
111 using unordered_map<PermissiveMatching, pc_to_sol*>::const_iterator;
112 using unordered_map<PermissiveMatching, pc_to_sol*>::erase;
113 using unordered_map<PermissiveMatching, pc_to_sol*>::empty;
114 using unordered_map<PermissiveMatching, pc_to_sol*>::emplace;
115 using unordered_map<PermissiveMatching, pc_to_sol*>::begin;
116 using unordered_map<PermissiveMatching, pc_to_sol*>::end;
117 using unordered_map<PermissiveMatching, pc_to_sol*>::find;
123 for(iterator old_i = begin(); old_i != end(); old_i = erase(old_i)){
125 DEBUG5(std::cout <<
"constructing a new map @"<<new_map<<
" by forgetting "<<(
unsigned)v_idx<<
" from P = "<<P<<std::endl);
127 const byte u_idx = P[v_idx];
131 new_P[u_idx] = u_idx;
132 new_P[v_idx] = v_idx;
134 new_map->merge(new_P, old_i->second);
136 DEBUG5(std::cout <<
"forgetting "<<(
unsigned)v_idx<<
" closes a path in matrix @"<<old_i->second<<std::endl);
139 new_map->merge(P, old_i->second);
146 P_to_pc_map* intro_edge(
const byte u_idx,
const byte v_idx,
const byte du,
const byte dv,
const EdgeName& en,
const size_t weight)
150 for(iterator old_i = begin(); old_i != end(); old_i = erase(old_i)){
152 pc_to_sol* sol_matrix = old_i->second;
156 const PathsAndCycles closed_pc = modify_P_with_uv(P, u_idx, du, v_idx, dv);
157 DEBUG5(std::cout <<
"modified P:"<<std::endl<<old_P<<std::endl<<P<<
" closing "<<closed_pc<<
" pc's"<<std::endl);
159 sol_matrix->add_to_each_key(closed_pc);
160 sol_matrix->add_to_all(en, weight);
163 new_map->merge(P, sol_matrix);
173 for(const_iterator old_i = begin(); old_i != end(); ++old_i)
175 const pc_to_sol*
const my_matrix = old_i->second;
179 const pc_to_sol*
const T_matrix = T_Ppc.second;
181 DEBUG5(std::cout <<
"merging:"<<std::endl<<old_i->first<<
" & "<<std::endl<<T_P<<
" to "<<std::endl);
183 DEBUG5(std::cout<<P<<std::endl);
187 pc_to_sol* pc =
new pc_to_sol(my_matrix->max);
189 for(
auto my_pc = my_matrix->get_entries(); my_pc.first != my_pc.second; ++my_pc.first)
190 for(
auto T_pc = T_matrix->get_entries(); T_pc.first != T_pc.second; ++T_pc.first){
191 DEBUG5(std::cout <<
"joining:"<< my_pc.first->first<<
" & " << T_pc.first->first<<
" --> "<< my_pc.first->first + T_pc.first->first + closed_pc<<std::endl);
193 if(!pc->put(my_pc.first->first + T_pc.first->first + closed_pc,ME))
delete ME;
196 new_map->merge(P, pc);
205 DEBUG5(std::cout <<
"merging "<<std::endl<<*pc<<
" into "<<P<<std::endl);
206 iterator i = find(P);
208 DEBUG6(std::cout <<
"merging the matrix "<<std::endl<<*pc<<
" with the present entry"<<std::endl<<*i->second<<
" for P = "<<P<<std::endl);
210 pc_to_sol* present_pc = i->second;
211 present_pc->destructive_merge(*pc);
214 DEBUG6(std::cout <<
"adding the matrix @"<<pc<<std::flush<<
" (size "<<pc->size()<<
") to P = "<<P<<std::endl);
218 DEBUG5(std::cout <<
"not merging now-empty matrix "<<std::endl);
226 DEBUG6(std::cout <<
"destructively merging "<<m.size()<<
" matrices"<<std::endl);
227 for(iterator i = m.begin(); i != m.end(); i = m.erase(i)) {
228 merge(i->first, i->second);
235 for(iterator i = begin(); i != end(); ++i){
236 DEBUG5(std::cout <<
"copying matrix with P = "<<i->first<<
" @"<<i->second<<
" (size "<<i->second->size()<<
")"<<std::endl);
238 pc_to_sol* pc =
new pc_to_sol(*i->second);
240 target.emplace(i->first, pc);
249 for(iterator i = begin(); i != end(); i = erase(i)){
252 new_map->emplace(P, i->second);
258 friend std::ostream& operator<<(std::ostream& os,
const P_to_pc_map& M)
260 for(
auto i = M.begin(); i != M.end(); ++i) os <<
"\t\t\t\t"<<i->first<<
":"<<std::endl<< *i->second << std::endl;
268 class d_to_P_map :
public unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >
271 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::iterator;
272 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::erase;
273 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::emplace;
274 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::begin;
275 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::end;
276 using unordered_map<DegMap, P_to_pc_map*, std::hash<DegMap> >::find;
282 for(iterator old_i = begin(); old_i != end(); old_i = erase(old_i)){
283 const DegMap& d = old_i->first;
289 DEBUG4(std::cout <<
"forgetting "<<(
unsigned)v_idx<<
" from entry with d = "<<d<<
" (new d = "<<new_d<<
")"<<std::endl);
292 P_to_pc_map* new_Ppc_map = old_Ppc_map->forget_vertex(v_idx);
295 old_i->second = NULL;
298 new_map->merge(new_d, new_Ppc_map);
299 }
else new_map->merge(d, old_i->second);
305 d_to_P_map* intro_edge(byte u_idx, byte v_idx,
const bool mu,
const bool mv,
const bool mu_old,
const bool mv_old,
const bool is_matching_edge,
const EdgeName& en,
const size_t weight)
310 if(!is_matching_edge){
311 DEBUG4(std::cout <<
"making a normal copy of the table to represent not-taking the edge ("<<en.first<<
","<<en.second<<
")"<<std::endl);
317 for(iterator old_i = begin(); old_i != end(); old_i = erase(old_i)){
318 const DegMap& d = old_i->first;
321 if(is_matching_edge || ((mu_old == d.test(u_idx)) && (mv_old == d.test(v_idx)))){
322 DEBUG4(std::cout <<
"taking "<<(is_matching_edge?
"M-":
" ")<<
"edge ("<<en.first<<
","<<en.second<<
") with indices ("<<(
unsigned)u_idx<<
","<<(
unsigned)v_idx<<
") & old M-values ("<<mu_old<<
","<<mv_old<<
") for d = "<<d<<std::endl);
328 byte du = mu + (new_d.test(u_idx) != mu);
329 byte dv = mv + (new_d.test(v_idx) != mv);
332 std::swap(u_idx, v_idx);
338 P_to_pc_map* new_Ppc = old_Ppc->intro_edge(u_idx, v_idx, du, dv, en, weight);
341 old_i->second = NULL;
343 new_map->merge(new_d, new_Ppc);
353 for(iterator old_i = begin(); old_i != end(); old_i = erase(old_i)){
355 const DegMap& my_d = old_i->first;
358 for(
auto& T_dPpc: T){
360 const DegMap& T_d = T_dPpc.first;
362 if(compatible(my_d, old_M, T_d, T_M)){
364 DEBUG5(std::cout <<
"--> merging d's:"<<std::endl<<my_d<<
" ("<<old_Ppc->size()<<
" P's) & "<< std::endl<<T_d<<
" ("<<T_Ppc.size() <<
" P's)"<<std::endl);
366 const DegMap& new_deg2 = my_d & T_d;
368 DegMap new_d = my_d ^ T_d;
370 P_to_pc_map* new_Ppc = old_Ppc->join(T_Ppc, new_deg2);
372 result->merge( new_d, new_Ppc);
376 for(
auto i = old_Ppc->begin(); i != old_Ppc->end(); ++i)
delete i->second;
378 old_i->second = NULL;
384 void merge(
const DegMap& d,
P_to_pc_map*
const Ppc)
387 iterator i = find(d);
389 DEBUG6(std::cout <<
"merging the map @"<<Ppc<<
" with the present entry (@"<<i->second<<
") for d = "<<d<<std::endl);
392 present_Ppc->destructive_merge(*Ppc);
394 }
else emplace(d, Ppc);
396 DEBUG5(std::cout <<
"not merging empty P_to_pc map into d = "<<d<<std::endl);
404 for(iterator i = begin(); i != end(); ++i){
405 DEBUG5(std::cout <<
"deep-copying entry with d = "<<i->first<<
" & map @"<<i->second<<std::endl);
408 i->second->make_copy(*Ppc);
410 target.emplace(i->first, Ppc);
419 for(iterator i = begin(); i != end(); i = erase(i)){
420 DegMap d = permute_degmap(i->first, perm);
421 P_to_pc_map* new_Ppc = i->second->apply_permutation(perm);
424 new_map->emplace(d, new_Ppc);
430 friend std::ostream& operator<<(std::ostream& os,
const d_to_P_map& M)
432 for(
auto i = M.begin(); i != M.end(); ++i) os <<
"\t\t"<<i->first<<
":"<<std::endl<< *i->second << std::endl;
446 template<
class Graph>
456 typedef boost::bimap< boost::bimaps::unordered_set_of<Vertex<Graph> >, boost::bimaps::unordered_set_of<byte> > VertexIndex;
466 void construct_index(
const VertexSet<Graph>& VSet)
468 for(
auto& v : VSet) intro_vertex(v);
475 index(
new VertexIndex()), table(
new DP_Entries())
477 construct_index(VSet);
480 DP_Table(
const Instance<Graph>& _I,
const TOL::GraphVertexSet& VSet, TOL::VTranslateBoostTOL<Graph>* vtranslate):
482 index(
new VertexIndex()), table(
new DP_Entries())
484 VertexSet<Graph> good_vset;
485 for(
auto& v: VSet) good_vset.emplace(vtranslate->right.at(v));
486 construct_index(good_vset);
490 ~
DP_Table(){
delete table;
delete index; }
496 for(
auto i = table->begin(); i != table->end(); ++i){
497 for(
auto j = i->second->begin(); j != i->second->end(); ++j)
delete j->second;
507 return table->empty();
510 void get_VSet(std::list<Vertex<Graph> >& l)
const
512 for(
auto& i: index->left) l.emplace_back(i.first);
522 void intro_vertex(
const Vertex<Graph>& v)
524 DEBUG3(std::cout <<
"introducing new vertex "<<VertexAndGraph<Graph>(v, *I.g)<<std::endl);
527 byte v_idx =
get(vertex_name, *I.g, v) % MAX_TW;
529 while(
contains(index->right, v_idx)) v_idx = (v_idx + 1) % MAX_TW;
530 index->left.insert(std::make_pair(v, v_idx));
535 void intro_vertices(
const VertexSet<Graph>& V)
537 for(
auto& v : V) intro_vertex(v);
542 void forget_vertex_from_table(
const byte& v_idx)
544 DP_Entries*
const old_table = table;
545 table = old_table->forget_vertex(v_idx);
547 DEBUG5(std::cout <<
"table after forgetting "<<(
unsigned)v_idx<<
":"<<std::endl<<*table<<std::endl);
549 void forget_vertex(
const Vertex<Graph>& v)
552 const auto i = index->left.find(v);
553 assert(i != index->left.end());
554 const byte v_idx = i->second;
555 DEBUG5(std::cout<<
"forgetting vertex["<<(
unsigned)v_idx<<
"] = "<< std::flush<<VertexAndGraph<Graph>(index->right.at(v_idx), *I.g)<<std::endl);
556 index->left.erase(i);
561 forget_vertex_from_table(v_idx);
565 void forget_vertices(
const VertexSet<Graph>& V)
567 for(
auto& v : V) forget_vertex(v);
572 void intro_edge_to_table(byte u_idx, byte v_idx,
const bool is_matching_edge,
const EdgeName& en,
const size_t weight)
575 bool mu_old = M_adj.test(u_idx);
576 bool mv_old = M_adj.test(v_idx);
578 if(is_matching_edge) {
579 assert(!mu_old && !mv_old);
587 DEBUG4(std::cout <<
"new M = "<<M_adj<<std::endl);
590 DP_Entries* old_table = table;
591 table = old_table->intro_edge(u_idx, v_idx, mu, mv, mu_old, mv_old, is_matching_edge, en, weight);
594 void intro_edge(
const Edge<Graph>& e)
596 DEBUG4(std::cout <<
"introducing edge "<<EdgeAndGraph<Graph>(e, *I.g)<<std::endl);
602 const bool is_in_M = I.is_matching_edge(e);
603 const Vertex<Graph> u = source(e, *I.g);
604 const Vertex<Graph> v = target(e, *I.g);
605 const auto iu = index->left.find(u);
606 const auto iv = index->left.find(v);
607 assert(iu != index->left.end());
608 assert(iv != index->left.end());
609 const byte u_idx = iu->second;
610 const byte v_idx = iv->second;
613 intro_edge_to_table(u_idx, v_idx, is_in_M, EdgeName(
get(vertex_name, *I.g, u),
get(vertex_name, *I.g, v)) ,
get(edge_weight, *I.g, e));
615 void intro_edges(
const std::list<Edge<Graph> >& E)
617 for(
auto& e : E) intro_edge(e);
622 void unify_indices(
const DP_Table& T)
626 for(
const auto& i : index->left){
627 const Vertex<Graph>& v = i.first;
628 const byte v_idx = i.second;
630 perm[v_idx] = T.index->left.at(v);
633 DEBUG3(std::cout <<
"remapping indices with permutation "<<perm<<std::endl);
635 VertexIndex* new_index =
new VertexIndex;
636 for(
const auto& i : index->left)
637 new_index->insert(
typename VertexIndex::value_type(i.first, perm[i.second]));
641 M_adj = permute_degmap(M_adj, perm);
643 DP_Entries* new_table = table->apply_permutation(perm);
645 }
else DEBUG3(std::cout <<
"rejoice, the indices are identical, saving the remap!"<<std::endl);
655 if(index->size() < T.index->size()) unify_indices(T);
else T.unify_indices(*
this);
659 DP_Entries* old_table = table;
662 DEBUG4(std::cout <<
"--> stealing size-"<<T.table->size()<<
" table from child"<<std::endl);
665 T.table =
new DP_Entries();
668 DEBUG4(std::cout <<
"--> new M = "<<M_adj<<std::endl);
670 DegMap old_M = M_adj;
675 DEBUG4(std::cout <<
"--> new M = "<<M_adj<<std::endl);
677 table = old_table->join(*T.table, old_M, T.M_adj);
685 DEBUG5(std::cout <<
"--> initializing leaf"<<std::endl);
686 typename d_to_P_map::iterator dPpc_i = table->emplace(DegMap(),
new P_to_pc_map()).first;
688 pc_to_sol& leaf_matrix = *Ppc_i->second;
696 for(
auto& i : *table)
697 for(
auto& j : *i.second)
698 result += j.second->size();
705 for(
auto& dPpc: *table)
706 for(
auto& Ppc: *dPpc.second)
707 for(
auto pc = Ppc.second->get_entries(); pc.first != pc.second; ++pc.first)
708 S.put(pc.first->first, pc.first->second);
711 friend std::ostream& operator<<(std::ostream& os,
const DP_Table& T)
713 for(
typename DP_Entries::iterator i = T.table->begin(); i != T.table->end(); ++i) os <<i->first<<
":"<<std::endl<< *i->second << std::endl;
bool is_identity() const
return whether everyone matches to itself
Definition: permissive_matching.hpp:98
PathsAndCycles merge_with(const PermissiveMatching &P, const std::bitset< ARRAY_LENGTH > °1_in_both)
TODO: move this out of the permissive matching class as it's unique to the DP code & this should be a...
Definition: permissive_matching.hpp:127
Definition: read_adj_list.hpp:22
unsigned num_cycles
max number of cycles in solutions
Definition: instance.hpp:33
Definition: dp_table.hpp:107
Definition: dp_solution.hpp:19
Definition: permissive_matching.hpp:25
void permute(const BytePermutation &perm)
rename the indices according to the given BytePermutation
Definition: permissive_matching.hpp:111
Definition: dp_table.hpp:447
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
Definition: dp_table.hpp:268