From 6ba84db324d2a227eb6ef8474e432c32aec2c1e1 Mon Sep 17 00:00:00 2001 From: wadmes Date: Mon, 16 Mar 2020 15:28:28 +0800 Subject: [PATCH] convert dl_opt into a new file --- src/DL_MPL.cpp | 5 +- src/DancingLinkColoring.h | 37 +- src/DancingLinkColoringOpt.h | 1152 ++++++++++++++++++++++++++++++++++ src/Enums.cpp | 2 + src/Enums.h | 3 +- src/Params.cpp | 4 +- src/SimpleMPL.cpp | 17 +- 7 files changed, 1185 insertions(+), 35 deletions(-) create mode 100644 src/DancingLinkColoringOpt.h diff --git a/src/DL_MPL.cpp b/src/DL_MPL.cpp index 5ff16444..a06c9091 100644 --- a/src/DL_MPL.cpp +++ b/src/DL_MPL.cpp @@ -815,16 +815,17 @@ int mask_number, std::vector>>& decode int No = ((*i) - 1) / mask_number + 1; int mask = (*i + 2) % mask_number; color_results_wo_stitch[No-1] = mask; } - + // std::cout<<"selected rows: "<<(*i)< (vertex_number * (uint32_t)(mask_number) + (uint32_t)1)){ std::vector>& row_decoder = decode_mat[(*i)- vertex_number * mask_number -2]; for(std::vector>::iterator it = row_decoder.begin(); it != row_decoder.end(); ++it) { color_vector[(*it).first] = (*it).second; + // std::cout<<"Corresponding color "<<(*it).first<<" "<<(*it).second<::iterator it = node_list.begin(); it != node_list.end(); ++it) { if(color_vector[(*it)->Stitch_No]!= -1){continue;} diff --git a/src/DancingLinkColoring.h b/src/DancingLinkColoring.h index 286afd73..f50b4f96 100644 --- a/src/DancingLinkColoring.h +++ b/src/DancingLinkColoring.h @@ -38,9 +38,8 @@ class DancingLinkColoring : public limbo::algorithms::coloring::Coloring & node_comp,uint32_t& comp_id,std::set & stitch_set){ std::stack vStack; @@ -477,8 +476,7 @@ class DancingLinkColoring : public limbo::algorithms::coloring::Coloringm_vColor,(int)vertex_numbers, (int32_t)this->color_num(), decode_mat,node_list); - double cost1 = new_calc_cost(this->m_vColor); + std::vector color_vector_dl1; + color_vector_dl1.assign(this->m_vColor.size(),-1); + decode_row_results(selected_rows_by_dl1, color_vector_dl1,(int)vertex_numbers, (int32_t)this->color_num(), decode_mat,node_list); + double cost1 = new_calc_cost(color_vector_dl1); //std::cout<< "FIRST DL GET RESULT" << dancing_link_timer.format(6)<m_vColor.swap(color_vector_dl1); + } if(cost1 > 0) { std::vector color_vector_dl2; @@ -754,10 +757,10 @@ class DancingLinkColoring : public limbo::algorithms::coloring::ColoringChilds).size(); uint32_t stitch_num = ((*it)->Stitches).size(); if(childs_num > 1){ - std::cout<<"node id: "<<(*it)->No<<", stitch_num: "<Childs).begin(); child != ((*it)->Childs).end(); ++child){ - std::cout<<"child count "<< (*child)->Stitch_No<No<<", stitch_num: "<Childs).begin(); child != ((*it)->Childs).end(); ++child){ + // std::cout<<"child count "<< (*child)->Stitch_No<color_num()) * (this->color_num()); @@ -776,8 +779,8 @@ class DancingLinkColoring : public limbo::algorithms::coloring::Coloringcolor_num() + 1 + stitch_count * pow((int32_t)this->color_num(),2); col_numbers = edge_numbers * (int32_t)this->color_num() + vertex_numbers; - std::cout<<"DL2: row/col is"<color_num(),2) * (childs_num -1); } - std::cout<<"ERROR:"< node_comp(node_list.size(), std::numeric_limits::max()); @@ -916,7 +918,7 @@ class DancingLinkColoring : public limbo::algorithms::coloring::Coloring::max()); connected_components_k_stitches(node_comp,comp_id,(*parent_node)->Childs,stitch_set); - std::cout<source"<source<target"<target<> row_decoder; //Insert node indicator - std::cout<<"Cell_Insert "<color_num() + 2+ starting_index <<" " <color_num() + 2+ starting_index <<" " <color_num() + 2+ starting_index, parent_no); // for(auto node_comp_item:node_comp){ // std::cout<<(node_comp_item)< cost2) + if(cost1 > cost2 && current_best_cost > cost2) { cost1 = cost2; this->m_vColor.swap(color_vector_dl2); diff --git a/src/DancingLinkColoringOpt.h b/src/DancingLinkColoringOpt.h new file mode 100644 index 00000000..e2eda4f3 --- /dev/null +++ b/src/DancingLinkColoringOpt.h @@ -0,0 +1,1152 @@ +/** + * @file DancingLinkColoringOpt.h + * @author Wei LI + * @date March 2020 + */ +#ifndef SIMPLEMPL_DANCINGLINKCOLORINGOPT_H +#define SIMPLEMPL_DANCINGLINKCOLORINGOPT_H + +#include +#include "DL_MPL.h" + +SIMPLEMPL_BEGIN_NAMESPACE + +template +class DancingLinkColoringOpt : public limbo::algorithms::coloring::Coloring +{ + public: + /// @nowarn + typedef limbo::algorithms::coloring::Coloring base_type; + using typename base_type::graph_type; + using typename base_type::graph_vertex_type; + using typename base_type::graph_edge_type; + using typename base_type::vertex_iterator_type; + using typename base_type::edge_iterator_type; + using typename base_type::edge_weight_type; + using typename base_type::ColorNumType; + + /// constructor + /// @param g graph + DancingLinkColoringOpt(graph_type const& g) + : base_type(g) + {} + /// destructor + virtual ~DancingLinkColoringOpt() {} + + protected: + /// kernel coloring algorithm + /// @return objective value + virtual double coloring() + { + double cost1 = solve_by_dancing_link_with_one_stitch(); + double cost2 = std::numeric_limits::max(); + if(cost1 > 0){ + cost2 = solve_by_dancing_link_with_at_most_two_stitches(cost1); + } + return std::min(cost1, cost2); + } + void dfs_search(uint32_t& source,std::vector & node_comp,uint32_t& comp_id,std::set & stitch_set){ + std::stack vStack; + uint32_t component_count = 0; + // std::cout<::max()) // not visited + { + node_comp[current] = comp_id;// set visited + component_count += 1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(current, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + std::pair e12 = boost::edge(current, v2, this->m_graph); + bool in_stitch_set = false; + for(auto stitch = stitch_set.begin(); stitch != stitch_set.end();++stitch){ + if(((*stitch)->source == current && (*stitch)->target == (int)v2) || ((*stitch)->source == (int)v2 && (*stitch)->target == current)){ + in_stitch_set = true; + break; + } + } + //if the stitch adj node is not connected by stitch in stitch_set, then we assign the same component + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0 && in_stitch_set == false){ + mplAssert(current != v2); + vStack.push(v2); + // std::cout< & node_comp, uint32_t& comp_id, std::vector & node_set, std::set & stitch_set){ + for(std::vector::iterator it = node_set.begin(); it != node_set.end(); ++it){ + // if not visited + uint32_t No = (uint32_t)((*it)->Stitch_No); + if(node_comp[No] ==std::numeric_limits::max()){ + dfs_search(No, node_comp,comp_id,stitch_set); + comp_id ++; + } + } + } + + double solve_by_dancing_link_with_one_stitch() + { + // Due to graph does not contain a parent&child node system + // we simply redesign a node struct to achieve this kind of system + //boost::timer::cpu_timer dancing_link_timer; + //dancing_link_timer.start(); + DancingLink dl; + std::vector node_list; + node_list.resize(num_vertices(this->m_graph)); + uint32_t vertex_numbers = 0; + uint32_t edge_numbers = 0; + vertex_iterator_type vi1, vie1; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //std::cout<m_graph, e12.first)<Conflicts.empty()); + node_list[v1] = source_vertex; + source_vertex->Stitch_No = v1; + vertex_numbers ++; + } + if(!node_list[v2]) + { + Vertex* target_vertex = new Vertex; + target_vertex->Stitch_No = v2; + node_list[v2] = target_vertex; + vertex_numbers ++; + } + + //if two nodes are stitch relationships and both of them are parent + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + //std::cout<<"Stitch:"<parent != NULL && node_list[v1]->parent== node_list[v2]->parent) continue; + Vertex* parent_vertex = new Vertex; + mplAssert(parent_vertex->Childs.empty()); + parent_vertex->parentOf(node_list[v1]); + parent_vertex->parentOf(node_list[v2]); + vertex_numbers -= 1; + continue; + } + node_list[v1]->Conflicts.insert(node_list[v2]); + } + } + //need to store node list, which does not contain child node + std::set node_wo_stitch_list; + int index = 1; + for(std::vector::iterator it = node_list.begin(); it != node_list.end(); ++it) + { + //if the node in parent node, means it has no stitch relations + (*it)->updateConflicts(); + if((*it)->Is_Parent) + { + node_wo_stitch_list.insert((*it)); + (*it)->No = index; + index ++; + } + //else, add its parent node if it has not been added into node_wo_stitch_list + else + { + mplAssertMsg((*it)->parent->Is_Parent, "%u\n%u\n", (uint32_t)(*it)->Stitch_No, (uint32_t)(*it)->parent->Stitch_No); + if(node_wo_stitch_list.find((*it)->parent) == node_wo_stitch_list.end()) + { + node_wo_stitch_list.insert((*it)->parent); + (*it)->parent->updateConflicts(); + (*it)->parent->No = index; + index ++; + } + + } + } + mplAssert(node_wo_stitch_list.size() == vertex_numbers); + std::vector > edge_list; + edge_list.resize(vertex_numbers + 1); + for(std::set::iterator it = node_wo_stitch_list.begin(); it != node_wo_stitch_list.end(); ++it) + { + mplAssert((*it)->No != 0); + for(std::set::iterator itconflict = (*it)->Conflicts_in_LG.begin(); itconflict != (*it)->Conflicts_in_LG.end(); ++itconflict) + { + if((*itconflict)->Is_Parent) + { + mplAssert((*itconflict)->No != 0); + edge_numbers++; + edge_list[(*it)->No].push_back(Edge_Simple{ (*itconflict)->No, (int)edge_numbers }); + edge_list[(*itconflict)->No].push_back(Edge_Simple{ (*it)->No, (int)edge_numbers }); + } + else + { + mplAssert((*itconflict)->parent->Is_Parent); + //avoid repeat (conflicts of stitch realation nodes may represent same conflict) + edge_numbers++; + edge_list[(*it)->No].push_back(Edge_Simple{ (*itconflict)->parent->No, (int)edge_numbers }); + edge_list[(*itconflict)->parent->No].push_back(Edge_Simple{ (*it)->No, (int)edge_numbers }); + } + } + } + //std::cout<<"EDGE list generated with size: "< starting_indexes; + uint32_t starting_index = 0; + + //Stitch Generation: recording strating index of each parent node block + for(std::set::iterator it = node_wo_stitch_list.begin(); it != node_wo_stitch_list.end(); ++it) + { + uint32_t childs_num = ((*it)->Childs).size(); + mplAssert(childs_num > 1 || childs_num == 0); + starting_indexes.push_back(starting_index); + if(childs_num > 1) + { + starting_index += 9*(childs_num-1); + } + } + //std::cout<< "Graph build" << dancing_link_timer.format(6)<color_num() + 1; + int col_numbers = edge_numbers * (int32_t)this->color_num() + vertex_numbers; + //std::cout<<"DL1: row/col is"<color_num(); ++i) + { + //Insert elements representing nodes color ( first edge_num cols) + Cell_Insert(dl,(it - 1)*(int32_t)this->color_num() + i,it); + for (auto j = edge_list[it].begin(); j != edge_list[it].end(); ++j) + { + //Insert elements representing edge conflict + Cell_Insert(dl,(it - 1)*(int32_t)this->color_num() + i,vertex_numbers + (j->No - 1)*(int32_t)this->color_num() + i); + } + } + } + for (uint32_t i = 0; i < edge_numbers; ++i) + { + for (int32_t j = 1; j <= (int32_t)this->color_num(); ++j) + //Insert singelon row + Cell_Insert(dl,vertex_numbers * (int32_t)this->color_num() + 1,vertex_numbers + i * (int32_t)this->color_num() + j); + } + + + for(std::vector::iterator it = node_list.begin(); it != node_list.end(); ++it) + { + //if the node in parent node, means it has no stitch relations + (*it)->updateDuplicateLGConflicts(); + if(!(*it)->Is_Parent) + //else, add its parent node if it has not been added into node_wo_stitch_list + { + mplAssert((*it)->parent->Is_Parent); + if(node_wo_stitch_list.find((*it)->parent) == node_wo_stitch_list.end()) + { + node_wo_stitch_list.insert((*it)->parent); + (*it)->parent->updateDuplicateLGConflicts(); + } + + } + } + //std::cout<< "FIRST DL insert" << dancing_link_timer.format(6)< selected_rows_by_dl1; + selected_rows_by_dl1 = core_solve_dl(dl,edge_list,row_numbers, col_numbers,(int)vertex_numbers,(int32_t)this->color_num()); + //decode_mat for transforming the selected row to represented color. First: node id, Second: color; + std::vector>> decode_mat; + //cost 1 is the cost of non-stitch solver + //std::cout<< "FIRST DL SOLVE" << dancing_link_timer.format(6)<m_vColor,(int)vertex_numbers, (int32_t)this->color_num(), decode_mat,node_list); + double cost1 = new_calc_cost(this->m_vColor); + //std::cout<< "FIRST DL GET RESULT" << dancing_link_timer.format(6)< 0) + { + std::vector color_vector_dl2; + color_vector_dl2.assign(this->m_vColor.size(),-1); + //Step 1, encode matrix generation + //if cost1 is larger than 1, which means that there is one more conflicts, than we insert stitch in the node + //1 st dim: num_parent node + 1 + //2 nd dim: num_stitch of this parent node + //3 rd pair: deivided child node set by this stitch / conflict parent nodes set of the child nodes set + std::vector,std::set>>> encode_mat; + for(uint32_t i = 0; i<=vertex_numbers; i++) + { + std::vector,std::set>> small_encode_mat; + encode_mat.push_back(small_encode_mat); + } + uint32_t stitch_count = 0; + //I traverse all of the stitch edges for getting the encode matrix + vertex_iterator_type vi1, vie1; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //if two nodes are stitch relationships + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + stitch_count ++ ; + std::set set1; + set1.insert(v1); + std::set set2; + set2.insert(v2); + push_adj_into_set(v1,this->m_graph,set1,set2); + push_adj_into_set(v2,this->m_graph,set2,set1); + //std::cout << node_list[v1]->parent->No <,std::set> encode_mat_per_stitch = std::make_pair(set1,set2); + encode_mat[node_list[v1]->parent->No].push_back(encode_mat_per_stitch); + } + } + } + //std::cout<< "SECOND encode matrix" << dancing_link_timer.format(6)<color_num() + 1 + stitch_count * pow((int32_t)this->color_num(),2); + col_numbers = edge_numbers * (int32_t)this->color_num() + vertex_numbers; + // std::cout<<"DL2: row/col is"<color_num(); ++i) + { + //Insert elements representing nodes color ( first edge_num cols) + Cell_Insert(dl2,(it - 1)*(int32_t)this->color_num() + i,it); + for (auto j = edge_list[it].begin(); j != edge_list[it].end(); ++j) + { + //Insert elements representing edge conflict + Cell_Insert(dl2,(it - 1)*(int32_t)this->color_num() + i,vertex_numbers + (j->No - 1)*(int32_t)this->color_num() + i); + } + } + } + for (uint32_t i = 0; i < edge_numbers; ++i) + { + for (int32_t j = 1; j <= (int32_t)this->color_num(); ++j) + //Insert singelon row + Cell_Insert(dl2,vertex_numbers * (int32_t)this->color_num() + 1,vertex_numbers + i * (int32_t)this->color_num() + j); + } + // Step 2 Decode matrix generation and Stitch Rows Cell Insertion + int count = -1; + std::vector starting_indexes; + uint32_t starting_index = 0; + for(auto parent_node = node_wo_stitch_list.begin(); parent_node != node_wo_stitch_list.end(); ++parent_node) + { + uint32_t childs_num = ((*parent_node)->Childs).size(); + int parent_no = (*parent_node)->No; + count++; + if(childs_num == 0){continue;} + mplAssert(childs_num > 1); + starting_indexes.push_back(starting_index); + for(uint32_t stitch_no = 0; stitch_no < childs_num - 1; stitch_no++) + { + std::set first_set = encode_mat[parent_no][stitch_no].first; + std::set second_set = encode_mat[parent_no][stitch_no].second; + for(auto first_color = 0 ; first_color < (int32_t)this->color_num(); first_color ++) + { + for(auto second_color = 0 ; second_color < (int32_t)this->color_num(); second_color ++) + { + //row_decoder indicates the represented color of this row + std::vector> row_decoder; + //Cell insertion: Node indicator of stitch row + Cell_Insert(dl2,vertex_numbers * (uint32_t)this->color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, parent_no); + for( auto first_set_element = first_set.begin(); first_set_element != first_set.end();first_set_element++) + { + row_decoder.push_back(std::make_pair(*first_set_element,first_color)); + } + for(auto second_set_element = second_set.begin(); second_set_element !=second_set.end();second_set_element++) + { + row_decoder.push_back(std::make_pair(*second_set_element, second_color)); + } + mplAssertMsg(row_decoder.size() == childs_num, "BUG FOUND! row_decoder.size() %lu, childs_num %u\n", row_decoder.size(), childs_num); + decode_mat.push_back(row_decoder); + //Cell insertion: conflict indicator of stitch row + //std::cout<<"FIRST SET "<Conflicts_in_LG).begin(); child_conflict != + (node_list[*first_set_element]->Conflicts_in_LG).end(); ++child_conflict) + { + int col_edge = -1; + for(std::list::iterator conflict_edge = edge_list[node_list[*first_set_element]->parent->No].begin();conflict_edge != edge_list[node_list[*first_set_element]->parent->No].end();++conflict_edge) + { + if((*conflict_edge).target == (*child_conflict)->No) + { + col_edge = (*conflict_edge).No; + break; + } + } + // mplAssert(col_edge!=-1); + // mplAssert(node_list[*first_set_element]->Stitch_No == *first_set_element); + // std::cout<<"COL EDGE is "<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + // first_color *(uint32_t)this->color_num() + second_color<<" "<< vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + first_color<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + first_color); + } + } + //std::cout<<"SECOND SET "<Conflicts_in_LG).begin(); child_conflict != + (node_list[*second_set_element]->Conflicts_in_LG).end(); ++child_conflict) + { + int col_edge = -1; + for(std::list::iterator conflict_edge = edge_list[node_list[*second_set_element]->parent->No].begin();conflict_edge != edge_list[node_list[*second_set_element]->parent->No].end();++conflict_edge) + { + if((*conflict_edge).target == (*child_conflict)->No) + { + col_edge = (*conflict_edge).No; + break; + } + } + //mplAssert(col_edge!=-1); + // std::cout<<"COL EDGE is "<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + // first_color *(uint32_t)this->color_num() + second_color<<" "<< vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + second_color<color_num() +2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + second_color); + + } + } + } + } + } + //for each parent node, there are 9 * stitch_No stitch rows totally + starting_index += pow((int32_t)this->color_num(),2) * (childs_num -1); + } + //std::cout<< "SECOND dl insert" << dancing_link_timer.format(6)<color_num(),2)* stitch_count) + // { + // std::cout<<"BUG FOUND!"<color_num(),2)* stitch_count<color_num(),2)* stitch_count); + //solve dl with stitches + std::vector selected_rows_by_dl2; + selected_rows_by_dl2 = core_solve_dl(dl2,edge_list,row_numbers, col_numbers,(int)vertex_numbers,(int32_t)this->color_num()); + //cost 1 is the cost of non-stitch solver + //std::cout<< "SECOND dl slver" << dancing_link_timer.format(6)<color_num(), decode_mat,node_list); + double cost2 = new_calc_cost(color_vector_dl2); + + //std::cout<< "SECOND dl get result" << dancing_link_timer.format(6)< cost2) + { + cost1 = cost2; + this->m_vColor.swap(color_vector_dl2); + } + } + return cost1; + } + + + double solve_by_dancing_link_with_at_most_two_stitches(double current_best_cost){ + // Due to graph does not contain a parent&child node system + // we simply redesign a node struct to achieve this kind of system + //boost::timer::cpu_timer dancing_link_timer; + //dancing_link_timer.start(); + DancingLink dl; + std::vector node_list; + node_list.resize(num_vertices(this->m_graph)); + uint32_t vertex_numbers = 0; + uint32_t edge_numbers = 0; + vertex_iterator_type vi1, vie1; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //std::cout<m_graph, e12.first)<Conflicts.empty()); + node_list[v1] = source_vertex; + source_vertex->Stitch_No = v1; + vertex_numbers ++; + } + if(!node_list[v2]) + { + Vertex* target_vertex = new Vertex; + target_vertex->Stitch_No = v2; + node_list[v2] = target_vertex; + vertex_numbers ++; + } + + //if two nodes are stitch relationships and both of them are parent + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + // std::cout<<"Stitch:"<parent != NULL && node_list[v1]->parent== node_list[v2]->parent) continue; + Vertex* parent_vertex = new Vertex; + mplAssert(parent_vertex->Childs.empty()); + parent_vertex->parentOf(node_list[v1]); + parent_vertex->parentOf(node_list[v2]); + vertex_numbers -= 1; + continue; + } + node_list[v1]->Conflicts.insert(node_list[v2]); + } + } + //need to store node list, which does not contain child node + std::set node_wo_stitch_list; + int index = 1; + for(std::vector::iterator it = node_list.begin(); it != node_list.end(); ++it) + { + //if the node in parent node, means it has no stitch relations + (*it)->updateConflicts(); + if((*it)->Is_Parent) + { + node_wo_stitch_list.insert((*it)); + (*it)->No = index; + index ++; + } + //else, add its parent node if it has not been added into node_wo_stitch_list + else + { + mplAssertMsg((*it)->parent->Is_Parent, "%u\n%u\n", (uint32_t)(*it)->Stitch_No, (uint32_t)(*it)->parent->Stitch_No); + if(node_wo_stitch_list.find((*it)->parent) == node_wo_stitch_list.end()) + { + node_wo_stitch_list.insert((*it)->parent); + (*it)->parent->updateConflicts(); + (*it)->parent->No = index; + index ++; + } + + } + } + mplAssert(node_wo_stitch_list.size() == vertex_numbers); + std::vector > edge_list; + edge_list.resize(vertex_numbers + 1); + for(std::set::iterator it = node_wo_stitch_list.begin(); it != node_wo_stitch_list.end(); ++it) + { + mplAssert((*it)->No != 0); + for(std::set::iterator itconflict = (*it)->Conflicts_in_LG.begin(); itconflict != (*it)->Conflicts_in_LG.end(); ++itconflict) + { + if((*itconflict)->Is_Parent) + { + mplAssert((*itconflict)->No != 0); + edge_numbers++; + edge_list[(*it)->No].push_back(Edge_Simple{ (*itconflict)->No, (int)edge_numbers }); + edge_list[(*itconflict)->No].push_back(Edge_Simple{ (*it)->No, (int)edge_numbers }); + } + else + { + mplAssert((*itconflict)->parent->Is_Parent); + //avoid repeat (conflicts of stitch realation nodes may represent same conflict) + edge_numbers++; + edge_list[(*it)->No].push_back(Edge_Simple{ (*itconflict)->parent->No, (int)edge_numbers }); + edge_list[(*itconflict)->parent->No].push_back(Edge_Simple{ (*it)->No, (int)edge_numbers }); + } + } + } + //std::cout<<"EDGE list generated with size: "< starting_indexes; + uint32_t starting_index = 0; + + //Stitch Generation: recording strating index of each parent node block + for(std::set::iterator it = node_wo_stitch_list.begin(); it != node_wo_stitch_list.end(); ++it) + { + uint32_t childs_num = ((*it)->Childs).size(); + mplAssert(childs_num > 1 || childs_num == 0); + starting_indexes.push_back(starting_index); + if(childs_num > 1) + { + starting_index += 9*(childs_num-1); + } + } + + //This step is to update Stitches set + int stitch_count = 0; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //if two nodes are stitch relationships and both of them are parent + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + std::cout<<"Stitch:"<parent == node_list[v2]->parent); + Edge* edge = new Edge{int(v1),int(v2),stitch_count}; + node_list[v1]->parent->Stitches.insert(edge); + // std::cout<<"Edge address is: "<<&edge<No: "<parent->No<source<target<No<parent->Stitches).begin(); stitch != (node_list[v1]->parent->Stitches).end(); ++stitch){ + // std::cout<<"stitch set source: "<< (*stitch)->source<target<No<color_num() + 1; + int col_numbers = edge_numbers * (int32_t)this->color_num() + vertex_numbers; + //std::cout<<"DL1: row/col is"<color_num(); ++i) + { + //Insert elements representing nodes color ( first edge_num cols) + Cell_Insert(dl,(it - 1)*(int32_t)this->color_num() + i,it); + for (auto j = edge_list[it].begin(); j != edge_list[it].end(); ++j) + { + //Insert elements representing edge conflict + Cell_Insert(dl,(it - 1)*(int32_t)this->color_num() + i,vertex_numbers + (j->No - 1)*(int32_t)this->color_num() + i); + } + } + } + for (uint32_t i = 0; i < edge_numbers; ++i) + { + for (int32_t j = 1; j <= (int32_t)this->color_num(); ++j) + //Insert singelon row + Cell_Insert(dl,vertex_numbers * (int32_t)this->color_num() + 1,vertex_numbers + i * (int32_t)this->color_num() + j); + } + + + for(std::vector::iterator it = node_list.begin(); it != node_list.end(); ++it) + { + //if the node in parent node, means it has no stitch relations + (*it)->updateDuplicateLGConflicts(); + if(!(*it)->Is_Parent) + //else, add its parent node if it has not been added into node_wo_stitch_list + { + mplAssert((*it)->parent->Is_Parent); + if(node_wo_stitch_list.find((*it)->parent) == node_wo_stitch_list.end()) + { + node_wo_stitch_list.insert((*it)->parent); + (*it)->parent->updateDuplicateLGConflicts(); + } + + } + } + //std::cout<< "FIRST DL insert" << dancing_link_timer.format(6)< selected_rows_by_dl1; + selected_rows_by_dl1 = core_solve_dl(dl,edge_list,row_numbers, col_numbers,(int)vertex_numbers,(int32_t)this->color_num()); + //decode_mat for transforming the selected row to represented color. First: node id, Second: color; + std::vector>> decode_mat; + //cost 1 is the cost of non-stitch solver + //std::cout<< "FIRST DL SOLVE" << dancing_link_timer.format(6)< color_vector_dl1; + color_vector_dl1.assign(this->m_vColor.size(),-1); + decode_row_results(selected_rows_by_dl1, color_vector_dl1,(int)vertex_numbers, (int32_t)this->color_num(), decode_mat,node_list); + double cost1 = new_calc_cost(color_vector_dl1); + //std::cout<< "FIRST DL GET RESULT" << dancing_link_timer.format(6)<m_vColor.swap(color_vector_dl1); + } + if(cost1 > 0) + { + std::vector color_vector_dl2; + color_vector_dl2.assign(this->m_vColor.size(),-1); + //Step 1, encode matrix generation + //if cost1 is larger than 1, which means that there is one more conflicts, than we insert stitch in the node + //1 st dim: num_parent node + 1 + //2 nd dim: num_stitch of this parent node + //3 rd pair: deivided child node set by this stitch / conflict parent nodes set of the child nodes set + std::vector,std::set>>> encode_mat; + for(uint32_t i = 0; i<=vertex_numbers; i++) + { + std::vector,std::set>> small_encode_mat; + encode_mat.push_back(small_encode_mat); + } + uint32_t stitch_count = 0; + //I traverse all of the stitch edges for getting the encode matrix + vertex_iterator_type vi1, vie1; + row_numbers = vertex_numbers * (int32_t)this->color_num() + 1; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //if two nodes are stitch relationships + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + stitch_count ++ ; + std::set set1; + set1.insert(v1); + std::set set2; + set2.insert(v2); + push_adj_into_set(v1,this->m_graph,set1,set2); + push_adj_into_set(v2,this->m_graph,set2,set1); + //std::cout << node_list[v1]->parent->No <,std::set> encode_mat_per_stitch = std::make_pair(set1,set2); + encode_mat[node_list[v1]->parent->No].push_back(encode_mat_per_stitch); + } + } + } + + for(std::set::iterator it = node_wo_stitch_list.begin(); it != node_wo_stitch_list.end(); ++it) { + uint32_t childs_num = ((*it)->Childs).size(); + uint32_t stitch_num = ((*it)->Stitches).size(); + if(childs_num > 1){ + // std::cout<<"node id: "<<(*it)->No<<", stitch_num: "<Childs).begin(); child != ((*it)->Childs).end(); ++child){ + // std::cout<<"child count "<< (*child)->Stitch_No<color_num()) * (this->color_num()); + if(childs_num > 2){ + // # of rows which select exactly two working stitches + // this part is done by hard-coding, actually the valid number of rows should be determined by recording the conflict relationship between sub-polygons divided by working stitches. + row_numbers += stitch_num *(stitch_num -1)/2* (this->color_num() * (this->color_num() -1 )*(this->color_num() -1)); + } + } + + } + //std::cout<< "SECOND encode matrix" << dancing_link_timer.format(6)<color_num() + 1 + stitch_count * pow((int32_t)this->color_num(),2); + col_numbers = edge_numbers * (int32_t)this->color_num() + vertex_numbers; + // std::cout<<"DL2: row/col is"<color_num(); ++i) + { + //Insert elements representing nodes color ( first edge_num cols) + Cell_Insert(dl2,(it - 1)*(int32_t)this->color_num() + i,it); + for (auto j = edge_list[it].begin(); j != edge_list[it].end(); ++j) + { + //Insert elements representing edge conflict + Cell_Insert(dl2,(it - 1)*(int32_t)this->color_num() + i,vertex_numbers + (j->No - 1)*(int32_t)this->color_num() + i); + } + } + } + for (uint32_t i = 0; i < edge_numbers; ++i) + { + for (int32_t j = 1; j <= (int32_t)this->color_num(); ++j) + //Insert singelon row + Cell_Insert(dl2,vertex_numbers * (int32_t)this->color_num() + 1,vertex_numbers + i * (int32_t)this->color_num() + j); + } + // Step 2 Decode matrix generation and Stitch Rows Cell Insertion + int count = -1; + std::vector starting_indexes; + uint32_t starting_index = 0; + for(auto parent_node = node_wo_stitch_list.begin(); parent_node != node_wo_stitch_list.end(); ++parent_node) + { + uint32_t childs_num = ((*parent_node)->Childs).size(); + int parent_no = (*parent_node)->No; + count++; + if(childs_num == 0){continue;} + mplAssert(childs_num > 1); + starting_indexes.push_back(starting_index); + for(uint32_t stitch_no = 0; stitch_no < childs_num - 1; stitch_no++) + { + std::set first_set = encode_mat[parent_no][stitch_no].first; + std::set second_set = encode_mat[parent_no][stitch_no].second; + for(auto first_color = 0 ; first_color < (int32_t)this->color_num(); first_color ++) + { + for(auto second_color = 0 ; second_color < (int32_t)this->color_num(); second_color ++) + { + //row_decoder indicates the represented color of this row + std::vector> row_decoder; + //Cell insertion: Node indicator of stitch row + Cell_Insert(dl2,vertex_numbers * (uint32_t)this->color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, parent_no); + for( auto first_set_element = first_set.begin(); first_set_element != first_set.end();first_set_element++) + { + row_decoder.push_back(std::make_pair(*first_set_element,first_color)); + } + for(auto second_set_element = second_set.begin(); second_set_element !=second_set.end();second_set_element++) + { + row_decoder.push_back(std::make_pair(*second_set_element, second_color)); + } + mplAssertMsg(row_decoder.size() == childs_num, "BUG FOUND! row_decoder.size() %lu, childs_num %u\n", row_decoder.size(), childs_num); + decode_mat.push_back(row_decoder); + //Cell insertion: conflict indicator of stitch row + //std::cout<<"FIRST SET "<Conflicts_in_LG).begin(); child_conflict != + (node_list[*first_set_element]->Conflicts_in_LG).end(); ++child_conflict) + { + int col_edge = -1; + for(std::list::iterator conflict_edge = edge_list[node_list[*first_set_element]->parent->No].begin();conflict_edge != edge_list[node_list[*first_set_element]->parent->No].end();++conflict_edge) + { + if((*conflict_edge).target == (*child_conflict)->No) + { + col_edge = (*conflict_edge).No; + break; + } + } + // mplAssert(col_edge!=-1); + // mplAssert(node_list[*first_set_element]->Stitch_No == *first_set_element); + // std::cout<<"COL EDGE is "<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + // first_color *(uint32_t)this->color_num() + second_color<<" "<< vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + first_color<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + first_color); + } + } + //std::cout<<"SECOND SET "<Conflicts_in_LG).begin(); child_conflict != + (node_list[*second_set_element]->Conflicts_in_LG).end(); ++child_conflict) + { + int col_edge = -1; + for(std::list::iterator conflict_edge = edge_list[node_list[*second_set_element]->parent->No].begin();conflict_edge != edge_list[node_list[*second_set_element]->parent->No].end();++conflict_edge) + { + if((*conflict_edge).target == (*child_conflict)->No) + { + col_edge = (*conflict_edge).No; + break; + } + } + //mplAssert(col_edge!=-1); + // std::cout<<"COL EDGE is "<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + // first_color *(uint32_t)this->color_num() + second_color<<" "<< vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + second_color<color_num() +2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + first_color *(uint32_t)this->color_num() + second_color, vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + second_color); + + } + } + } + } + } + //for each parent node, there are 9 * stitch_No stitch rows totally + starting_index += pow((int32_t)this->color_num(),2) * (childs_num -1); + } + + + //Now, we insert exactly two stitches + std::vector node_comp(node_list.size(), std::numeric_limits::max()); + for(auto parent_node = node_wo_stitch_list.begin(); parent_node != node_wo_stitch_list.end(); ++parent_node) + { + uint32_t childs_num = ((*parent_node)->Childs).size(); + int parent_no = (*parent_node)->No; + count++; + if(childs_num == 0){continue;} + mplAssert(childs_num > 1); + starting_indexes.push_back(starting_index); + //DYNAMIC TODO: Here we hard-code select two stitches as working stitches. If we need a dynamic k stitches, a recursive func is needed + for(auto stitch1 = (*parent_node)->Stitches.begin(); stitch1 != (*parent_node)->Stitches.end(); ++stitch1){ + for(auto stitch2 = (*parent_node)->Stitches.begin(); stitch2 != (*parent_node)->Stitches.end(); ++stitch2){ + //if two stitches are the same, it equals to the one stitch situation + if((*stitch1)->No < (*stitch2)->No){ + std::set stitch_set; + stitch_set.insert(*stitch1); + stitch_set.insert(*stitch2); + uint32_t comp_id = 0; + std::fill(node_comp.begin(), node_comp.end(), std::numeric_limits::max()); + connected_components_k_stitches(node_comp,comp_id,(*parent_node)->Childs,stitch_set); + // std::cout<source"<source<target"<target<Stitches){ + // std::cout<<"all stitch->source"<source<target"<target< colors(comp_id, std::numeric_limits::max()); + for(uint32_t color0 = 0; color0 < this->color_num(); color0++){ + for(uint32_t color1 = 0; color1 < this->color_num();color1++){ + for(uint32_t color2 = 0; color2 < this->color_num();color2++){ + colors[0] = color0; + colors[1] = color1; + colors[2] = color2; + bool is_invalid = false; + for(auto stitch = stitch_set.begin(); stitch != stitch_set.end(); ++stitch){ + mplAssert(node_comp[(*stitch)->source] != node_comp[(*stitch)->target]); + //if two components seperated by one working stitch share same color: then this is invalid! (the stitch is not working!) + if(colors[node_comp[(*stitch)->source]] == colors[node_comp[(*stitch)->target]]){ + is_invalid = true; + break; + } + } + if(is_invalid) continue; + //otherwise, we insert the color combination as one row. + + std::vector> row_decoder; + //Insert node indicator + // std::cout<<"Cell_Insert "<color_num() + 2+ starting_index <<" " <color_num() + 2+ starting_index, parent_no); + // for(auto node_comp_item:node_comp){ + // std::cout<<(node_comp_item)<Childs.begin(); child_node != (*parent_node)->Childs.end(); ++child_node){ + int No = (*child_node)->Stitch_No; + // std::cout<<"No is "<Conflicts_in_LG).begin(); child_conflict != + ((*child_node)->Conflicts_in_LG).end(); ++child_conflict) + { + int col_edge = -1; + // This step is to find col_edge to locate the col number. + for(std::list::iterator conflict_edge = edge_list[(*child_node)->parent->No].begin();conflict_edge != edge_list[(*child_node)->parent->No].end();++conflict_edge) + { + if((*conflict_edge).target == (*child_conflict)->No) + { + col_edge = (*conflict_edge).No; + break; + } + } + // mplAssert(col_edge!=-1); + // mplAssert(node_list[*first_set_element]->Stitch_No == *first_set_element); + // std::cout<<"COL EDGE is "<color_num() + 2+ starting_index + (stitch_no*pow((uint32_t)this->color_num(),2)) + + // first_color *(uint32_t)this->color_num() + second_color<<" "<< vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + first_color<color_num() + 2+ starting_index <<" " <color_num() + colors[node_comp[No]]<color_num() + 2+ starting_index, vertex_numbers + 1+(col_edge -1)*(uint32_t)this->color_num() + colors[node_comp[No]]); + } + row_decoder.push_back(std::make_pair((uint32_t)No,colors[node_comp[No]])); + } + decode_mat.push_back(row_decoder); + starting_index += 1; + } + } + } + } + } + } + } + //std::cout<< "SECOND dl insert" << dancing_link_timer.format(6)<color_num(),2)* stitch_count) + // { + // std::cout<<"BUG FOUND!"<color_num(),2)* stitch_count<color_num(),2)* stitch_count); + //solve dl with stitches + std::vector selected_rows_by_dl2; + selected_rows_by_dl2 = core_solve_dl(dl2,edge_list,row_numbers, col_numbers,(int)vertex_numbers,(int32_t)this->color_num()); + //cost 1 is the cost of non-stitch solver + //std::cout<< "SECOND dl slver" << dancing_link_timer.format(6)<color_num(), decode_mat,node_list); + double cost2 = new_calc_cost(color_vector_dl2); + + //std::cout<< "SECOND dl get result" << dancing_link_timer.format(6)< cost2 && current_best_cost > cost2) + { + cost1 = cost2; + this->m_vColor.swap(color_vector_dl2); + } + } + return cost1; + } + //find the node with maximal degree, + //return: the node id with maximal degree + //iteratively mark the nodes which locate in some polygon (for new_calc_cost function) + void iterative_mark(graph_type const& g, std::vector& parent_node_ids, graph_vertex_type& v1) const + { + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, g); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + std::pair e12 = boost::edge(v1, v2, g); + mplAssert(e12.second); + //if two nodes are stitch relationships + if(boost::get(boost::edge_weight, g, e12.first) < 0) + { + if(parent_node_ids[(uint32_t)v2] == (uint32_t)-1) + { + parent_node_ids[(uint32_t)v2] = parent_node_ids[(uint32_t)v1]; + iterative_mark(g, parent_node_ids,v2); + } + else + { + mplAssert(parent_node_ids[(uint32_t)v2] == parent_node_ids[(uint32_t)v1]); + } + } + } + } + + //calculate cost, used in dancing link + virtual double new_calc_cost(std::vector const& vColor) const + { + double cost = 0; + std::vector parent_node_ids; + parent_node_ids.assign(boost::num_vertices(this->m_graph),-1); + uint32_t parent_node_id = 0; + vertex_iterator_type vi1, vie1; + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + mplAssert(vColor[v1]!=-1); + if(parent_node_ids[(uint32_t)v1] == (uint32_t)-1) + { + parent_node_ids[(uint32_t)v1] = parent_node_id; + iterative_mark(this->m_graph,parent_node_ids,v1); + parent_node_id++; + } + } + + + //calculate conflict by parent node + std::vector> conflict_mat; + for(uint32_t i = 0; i < parent_node_id; i++) + { + std::vector row_mat; + row_mat.assign(parent_node_id,false); + conflict_mat.push_back(row_mat); + } + + for (boost::tie(vi1, vie1) = boost::vertices(this->m_graph); vi1 != vie1; ++vi1) + { + graph_vertex_type v1 = *vi1; + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, this->m_graph); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + if (v1 >= v2) continue; + std::pair e12 = boost::edge(v1, v2, this->m_graph); + mplAssert(e12.second); + //if two nodes are stitch relationships and both of them are parent + if(boost::get(boost::edge_weight, this->m_graph, e12.first) < 0) + { + //std::cout<<"Stitch:"<stitch_weight(); + } + else + { + if(vColor[v1] == vColor[v2]) + { + if(conflict_mat[parent_node_ids[(uint32_t)v1]][parent_node_ids[(uint32_t)v2]] == false) + { + cost += 1; + conflict_mat[parent_node_ids[(uint32_t)v1]][parent_node_ids[(uint32_t)v2]] = true; + conflict_mat[parent_node_ids[(uint32_t)v2]][parent_node_ids[(uint32_t)v1]] = true; + } + } + } + } + } + + return cost; + } + + //push stitch adjacents nodes into same des_set used in solve_by_dancing_link_with_one_stitch. + void push_adj_into_set(graph_vertex_type const& v1, graph_type const& g, std::set & des_set, std::set const& oppo_set) + { + typename boost::graph_traits::adjacency_iterator vi2, vie2,next2; + boost::tie(vi2, vie2) = boost::adjacent_vertices(v1, g); + for (next2 = vi2; vi2 != vie2; vi2 = next2) + { + ++next2; + graph_vertex_type v2 = *vi2; + std::pair e12 = boost::edge(v1, v2, g); + mplAssert(e12.second); + //if two nodes are stitch relationships + if(boost::get(boost::edge_weight, g, e12.first) < 0) + { + //if the node has not been seted into the set + //std::cout<<"v1 "< diff --git a/src/Params.cpp b/src/Params.cpp index 8849d58b..c48ac0a2 100644 --- a/src/Params.cpp +++ b/src/Params.cpp @@ -34,7 +34,7 @@ bool CmdParser::operator()(int argc, char** argv) .add_option(Value >("-path_layer", &parms.sPathLayer, "an integer indicating layer for conflict edges")) .add_option(Value >("-precolor_layer", &parms.sPrecolorLayer, "an integer indicating layer for pre-colored patterns")) .add_option(Value >("-uncolor_layer", &parms.sUncolorLayer, "an integer indicating layer for coloring")) - .add_option(Value("-algo", &algo_str, "algorithm type < ILP|BACKTRACK|LP|SDP >").default_value(std::string(defaultParms.algo))) + .add_option(Value("-algo", &algo_str, "algorithm type < ILP|ILP_UPDATED|BACKTRACK|LP|SDP|DL|DL_OPT >").default_value(std::string(defaultParms.algo))) .add_option(Value("-shape", &shape_str, "shape mode < RECTANGLE|POLYGON >").default_value(std::string(defaultParms.shape_mode))) .add_option(Value("-verbose", &parms.verbose, "toggle controling screen messages").toggle(true).default_value(defaultParms.verbose).toggle_value(true)) .add_option(Value("-use_stitch", &parms.use_stitch, "whether use stitch projection").toggle(true).default_value(defaultParms.use_stitch).toggle_value(true)) @@ -102,6 +102,8 @@ bool CmdParser::operator()(int argc, char** argv) parms.algo = AlgorithmTypeEnum::BACKTRACK; else if (limbo::iequals(algo_str, "DL")) parms.algo = AlgorithmTypeEnum::DANCING_LINK; + else if (limbo::iequals(algo_str, "DL_OPT")) + parms.algo = AlgorithmTypeEnum::DANCING_LINK_OPT; else mplPrint(kWARN, "Unknown algorithm type %s, set to default algorithm\n", algo_str.c_str()); // post processing shape_str diff --git a/src/SimpleMPL.cpp b/src/SimpleMPL.cpp index af75cbf0..c7d31550 100644 --- a/src/SimpleMPL.cpp +++ b/src/SimpleMPL.cpp @@ -40,6 +40,7 @@ #endif #include #include "DancingLinkColoring.h" +#include "DancingLinkColoringOpt.h" #define CUT_DG #ifdef DEBUG_NONINTEGERS std::vector vLP1NonInteger; @@ -2048,6 +2049,9 @@ lac::Coloring* SimpleMPL::create_coloring_solver(SimpleMP case AlgorithmTypeEnum::DANCING_LINK: pcs = new DancingLinkColoring (sg); break; + case AlgorithmTypeEnum::DANCING_LINK_OPT: + pcs = new DancingLinkColoringOpt (sg); + break; default: mplAssertMsg(0, "unknown algorithm type"); } } @@ -3197,19 +3201,6 @@ double SimpleMPL::solve_graph_coloring_with_remove_stitch_redundancy(int depth, // 2nd trial, call solve_graph_coloring() again with MERGE_SUBK4 simplification only double obj_value2 = std::numeric_limits::max(); -#ifdef DEBUG_NONINTEGERS - std::set s_vdd_set; - for (uint32_t i = 0; i < vSimpl2Orig.size(); i++) - { - if (vdd_set.find(vSimpl2Orig[i]) != vdd_set.end()) - { - s_vdd_set.insert(i); - } - } - // very restrict condition to determin whether perform MERGE_SUBK4 or not - if (obj_value1 >= 1 && boost::num_vertices(sg) > 4 && (m_db->algo() == AlgorithmTypeEnum::LP_GUROBI || m_db->algo() == AlgorithmTypeEnum::SDP_CSDP) && (simplify_strategy & graph_simplification_type::MERGE_SUBK4) == 0) // MERGE_SUBK4 is not performed - obj_value2 = solve_graph_coloring(comp_id, sg, itBgn, pattern_cnt, graph_simplification_type::MERGE_SUBK4, vSubColor, s_vdd_set); // call again -#endif if (obj_value1 < obj_value2) {