From 1e6367ae19b69581611d526eca7323f9b50f9919 Mon Sep 17 00:00:00 2001 From: Florian <florian.heinrichs@informatik.hu-berlin.de> Date: Tue, 30 Apr 2019 11:52:41 +0200 Subject: [PATCH] remove endless lope cause by next_possible_partition; fixed correctness of algorithm; first decision doesn't create 2 branches anymore (symmetrie) --- bnb/bnb.cpp | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/bnb/bnb.cpp b/bnb/bnb.cpp index c2d9261..47dca5a 100644 --- a/bnb/bnb.cpp +++ b/bnb/bnb.cpp @@ -27,16 +27,14 @@ solver::solver(graph& g) : graph_(g), partition_(partition{g}) { } void solver::solve() { - //anfangs upper bound? + //anfangs lower bound? best_objective_ = graph_.num_nodes(); - //partition vector initializieren - - while(true) { - //falls current sol schlechter als obere grenze: + //falls current sol schlechter als bisher beste lösung: //zähle schritte bis zur nächsten alternative und + if(partition_.current_objective() >= best_objective_) { int i = trail_.length() - 1; while(true) { @@ -51,7 +49,7 @@ void solver::solve() { auto node = trail_.node_at(i); auto alt = trail_.alternative_at(i); //backtracke soviele schritte und - while(trail_.length() > i){ + while((int)trail_.length() > i){ backtrack(); } //wende dann die entsprechende alternative an @@ -61,28 +59,32 @@ void solver::solve() { // Memorize the new solution. best_solution_.resize(graph_.num_nodes()); for(node_id node = 0; node < graph_.num_nodes(); node++){ - best_solution_[node] = partition_.assigned_subgraph_of(node); + best_solution_[node] = partition_.assigned_subgraph_of(node+1); } best_objective_ = partition_.current_objective(); std::cerr << "Solution improved to k = " << best_objective_ << std::endl; }else{ //sonst expandiere suchbaum weiter - int node = trail_.length(); + int node = trail_.length() +1; expand(node, next_possible_subgraph(node, subgraph::sg_a)); } } } void solver::expand(node_id node, subgraph sg) { + assert(sg == subgraph::sg_a || sg == subgraph::sg_b); // Search for an alternative BEFORE assigning the node. // Because the node is not assigned, this calculation is easy. - auto alt = next_possible_subgraph(node, static_cast<subgraph>(-sg)); + subgraph alt; + if(partition_.num_nodes_of(subgraph::sg_a) == 0 && partition_.num_nodes_of(subgraph::sg_b)){ + alt = subgraph::none; + }else{ + alt = next_possible_subgraph(node, static_cast<subgraph>(sg +2)); + } if(verbose) { std::cerr << "Assign node " << node << " to subgraph " << sg << std::endl; std::cerr << " Alternative " << alt << std::endl; } - - std::vector<unsigned int> neighbors = graph_.get_adjacency(node); partition_.assign_node(node, sg); trail_.push_node(node, alt); @@ -104,16 +106,18 @@ subgraph solver::next_possible_subgraph(node_id node, subgraph m) { // This function is only correct if the node is not assigned yet. assert(partition_.assigned_subgraph_of(node) == subgraph::none); - // partition_count_: Index+1 of last partition that we will try. subgraph sg = m; - - //falls in einer partition schon die hälfte der knoten: nicht als alt wählen - if((partition_.num_nodes_of(sg) * 2) < graph_.num_nodes()){ - return sg; - } - else{ - return subgraph::none; + + while(sg <= 1){ + if((partition_.num_nodes_of(sg) * 2) < graph_.num_nodes()) + return sg; + else + { + sg = static_cast<subgraph>(sg+2); + } } + + return subgraph::none; } } // namespace gp_bnb -- GitLab