diff --git a/bnb/bnb.cpp b/bnb/bnb.cpp index 47dca5a069c55c72b8d4dadcefcfb3ac650b925b..f5d6fc36ca4ad497b51fc38a21c4b5240b72fe74 100644 --- a/bnb/bnb.cpp +++ b/bnb/bnb.cpp @@ -1,9 +1,15 @@ #include <cassert> #include <iostream> +#include <time.h> #include <gp-bnb/bnb.hpp> static constexpr bool verbose = false; +int visited_nodes = 0; +bool ibfs; +bool ek; +bool pr; +bool gp; namespace gp_bnb { @@ -26,20 +32,65 @@ void trail_state::pop() { solver::solver(graph& g) : graph_(g), partition_(partition{g}) { } +unsigned int solver::get_lower(){ + unsigned int lower_bound; + if(ek){ + std::vector<node_id> sources, sinks; + for(node_id node = 1; node <= graph_.num_nodes(); node++){ + if(partition_.assigned_subgraph_of(node) == partition::sg_a) + sources.push_back(node); + else if(partition_.assigned_subgraph_of(node) == partition::sg_b) + sinks.push_back(node); + } + auto ek = edmonds_karp(graph_, sources, sinks); + ek.run(); + lower_bound = ek.get_max_flow(); + } + else if(ibfs){ + std::vector<node_id> sources, sinks; + for(node_id node = 1; node <= graph_.num_nodes(); node++){ + if(partition_.assigned_subgraph_of(node) == partition::sg_a) + sources.push_back(node); + else if(partition_.assigned_subgraph_of(node) == partition::sg_b) + sinks.push_back(node); + } + auto i_bfs = incremental_bfs(graph_, sources, sinks); + i_bfs.run(); + lower_bound = i_bfs.get_max_flow(); + + } + else if(pr){ + + } + else if(gp){ + + } + else{ + lower_bound = partition_.current_objective(); + } + + return lower_bound; +} + void solver::solve() { //anfangs lower bound? best_objective_ = graph_.num_nodes(); - + clock_t begin = clock(); + //ek = true; + //ibfs = true; while(true) { //falls current sol schlechter als bisher beste lösung: //zähle schritte bis zur nächsten alternative und - if(partition_.current_objective() >= best_objective_) { + + if(get_lower() >= best_objective_) { int i = trail_.length() - 1; while(true) { - if(i < 0) + if(i < 0){ + std::cerr << "visited nodes: " << visited_nodes << std::endl; return; + } // Only backtrack to assignments that have an alternative. if(trail_.alternative_at(i) != subgraph::none) break; @@ -62,11 +113,29 @@ void solver::solve() { best_solution_[node] = partition_.assigned_subgraph_of(node+1); } best_objective_ = partition_.current_objective(); - std::cerr << "Solution improved to k = " << best_objective_ << std::endl; + clock_t end = clock(); + double time = (double)(end -begin) / CLOCKS_PER_SEC; + std::cerr << "Solution improved to k = " << best_objective_ << " after : " << time << " seconds and: " << visited_nodes << " besuchten knoten" << std::endl; }else{ //sonst expandiere suchbaum weiter - int node = trail_.length() +1; - expand(node, next_possible_subgraph(node, subgraph::sg_a)); + int next_node; + + //sort after degree + /*int node_deg = 0; + for(node_id node = 1; node <= graph_.num_nodes(); node++){ + if(partition_.assigned_subgraph_of(node) == subgraph::none){ + if(graph_.get_adjacency(node).size() > node_deg){ + node_deg = graph_.get_adjacency(node).size(); + next_node = node; + } + } + } + */ + + + next_node = trail_.length() +1; + + expand(next_node, next_possible_subgraph(next_node, subgraph::sg_a)); } } } @@ -76,6 +145,7 @@ void solver::expand(node_id node, subgraph sg) { // Search for an alternative BEFORE assigning the node. // Because the node is not assigned, this calculation is easy. subgraph alt; + visited_nodes++; if(partition_.num_nodes_of(subgraph::sg_a) == 0 && partition_.num_nodes_of(subgraph::sg_b)){ alt = subgraph::none; }else{ @@ -95,7 +165,7 @@ void solver::backtrack() { auto node = trail_.node_at(trail_.length() - 1); if(verbose) - std::cout << "Unassign node " << node << std::endl; + std::cout << "Unassign node " << node << std::endl; trail_.pop(); partition_.unassign_node(node); diff --git a/include/gp-bnb/bnb.hpp b/include/gp-bnb/bnb.hpp index a79f4783e8b9ee3812813a5d324ae04dd73545a2..7a4afe9692711bf539d323e85322ca6000e529f7 100644 --- a/include/gp-bnb/bnb.hpp +++ b/include/gp-bnb/bnb.hpp @@ -6,6 +6,8 @@ #include <gp-bnb/graph.hpp> #include <gp-bnb/partition.hpp> +#include <gp-bnb/edmonds_karp.hpp> +#include <gp-bnb/incremental_bfs.hpp> namespace gp_bnb { @@ -62,6 +64,8 @@ struct solver { return best_solution_; } + unsigned int get_lower(); + // Expand a search tree node, i.e., assigns an node to a partition and update all data structures. void expand(node_id node, subgraph sg);