Commit 340c2803 authored by Jonas Seidel's avatar Jonas Seidel
Browse files

bfs increase versatility

parent f0387bae
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
// _advanced.cpp: // _advanced.cpp:
Graph(std::istream& is); Graph(std::istream& is);
void conditional_bfs_all_components(std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_exec, std::function<void(Node<N,E>*)> node_exec,std::function<bool(Node<N,E>* from, Edge<N,E>* via)> guide = [](Node<N,E>* n, Edge<N,E>* e)->bool {return e->from() == n;}); void conditional_bfs_all_components(std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_exec, std::function<bool(Edge<N,E>* via, Node<N,E>* node)> node_exec, std::deque<Node<N,E>*> starting_nodes = {}, bool all_paths = false, std::function<bool(Node<N,E>* from, Edge<N,E>* via)> guide = [](Node<N,E>* n, Edge<N,E>* e)->bool {return e->from() == n;});
// _special_members_and_operators: // _special_members_and_operators:
void operator=(Graph<N,E>& graph); void operator=(Graph<N,E>& graph);
...@@ -77,7 +77,7 @@ template <typename N, typename E> ...@@ -77,7 +77,7 @@ template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Graph<N,E>& g); std::ostream& operator<<(std::ostream& os, Graph<N,E>& g);
template <typename N, typename E> template <typename N, typename E>
std::istream& operator>>(std::istream& is, Graph<N,E>& g){g = Graph(is); return is;} std::istream& operator>>(std::istream& is, Graph<N,E>& g){g = Graph<N,E>(is); return is;}
#include "Basic_Graph.ipp" #include "Basic_Graph.ipp"
#include "Basic_Graph_advanced.ipp" #include "Basic_Graph_advanced.ipp"
......
...@@ -30,7 +30,7 @@ Graph<N,E>::Graph(std::istream& is){ ...@@ -30,7 +30,7 @@ Graph<N,E>::Graph(std::istream& is){
is >> curr; is >> curr;
while(curr == "Edge"){ while(curr == "Edge"){
is.seekg(pos); is.seekg(pos);
Edge<N,E>* tmp = new Edge(is, name_lookup); Edge<N,E>* tmp = new Edge<N,E>(is, name_lookup);
this->_edges.insert(tmp); this->_edges.insert(tmp);
pos = is.tellg(); pos = is.tellg();
is >> curr; is >> curr;
...@@ -38,29 +38,44 @@ Graph<N,E>::Graph(std::istream& is){ ...@@ -38,29 +38,44 @@ Graph<N,E>::Graph(std::istream& is){
} }
template <typename N, typename E> template <typename N, typename E>
void Graph<N,E>::conditional_bfs_all_components(std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_exec, std::function<void(Node<N,E>*)> node_exec,std::function<bool(Node<N,E>* from, Edge<N,E>* via)> guide){ void Graph<N,E>::conditional_bfs_all_components(
std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_exec,
std::function<bool(Edge<N,E>* via, Node<N,E>* node)> node_exec,
std::deque<Node<N,E>*> starting_nodes,
bool all_paths,
std::function<bool(Node<N,E>* from, Edge<N,E>* via)> guide){
/* /*
executes edge_exec and node_exec for every edge or node in visiting order. Also executes for unused edges that test positive w.r.t guide executes edge_exec and node_exec for every edge or node in visiting order. Also executes for unused edges that test positive w.r.t guide
!! possibly executes twice if guide allows !! !! possibly executes twice if guide allows !!
node_exec will be called with nullptr for via for start node
node_exec might be called with nullptr for via if the graph is not strongly connected
node_exec need to return true in order to continue traversal over its incident edges
*/ */
std::set<Node<N,E>*> uncharted = this->nodes(); std::set<Node<N,E>*> uncharted = this->nodes();
std::queue<Node<N,E>*> active; std::deque<Node<N,E>*> active = starting_nodes;
while(!uncharted.empty()){ while(!uncharted.empty()){
active.push(*uncharted.begin()); if(active.empty()){
active.push_back(*uncharted.begin());
uncharted.erase(*uncharted.begin()); uncharted.erase(*uncharted.begin());
}
for(Node<N,E>* manually_inserted_node : active){
node_exec(nullptr, manually_inserted_node);
}
while(!active.empty()){ while(!active.empty()){
Node<N,E>* n = active.front(); active.pop(); Node<N,E>* n = active.front(); active.pop_front();
node_exec(n);
for(Edge<N,E>* e : n->incident()){ for(Edge<N,E>* e : n->incident()){
bool used_in_traversal = false; bool used_in_traversal = false;
if(guide(n, e)){ if(guide(n, e)){
if(uncharted.find(e->to(n)) != uncharted.end()){ if(uncharted.find(e->to(n)) != uncharted.end() || all_paths){
used_in_traversal = true; used_in_traversal = true;
active.push(e->to(n)); if(node_exec(e, e->to(n))){
active.push_back(e->to(n));
}
uncharted.erase(e->to(n)); uncharted.erase(e->to(n));
} }
......
...@@ -37,12 +37,13 @@ std::pair<std::map<std::pair<Node<N,E>*,N>, std::pair<Variable*, size_t>>, std:: ...@@ -37,12 +37,13 @@ std::pair<std::map<std::pair<Node<N,E>*,N>, std::pair<Variable*, size_t>>, std::
edge_lookup.insert({{via, edge_prop.first}, p.add_variable(Variable(name.str(), std::get<0>(edge_prop.second), std::get<1>(edge_prop.second), std::get<2>(edge_prop.second)))}); edge_lookup.insert({{via, edge_prop.first}, p.add_variable(Variable(name.str(), std::get<0>(edge_prop.second), std::get<1>(edge_prop.second), std::get<2>(edge_prop.second)))});
} }
}; };
std::function<void(Node<N,E>*)> node_function = [&p, &node_lookup, &node_var_data, start_index, name_appendix](Node<N,E>* n) -> void { std::function<bool(Edge<N,E>*, Node<N,E>*)> node_function = [&p, &node_lookup, &node_var_data, start_index, name_appendix](Edge<N,E>* via, Node<N,E>* n) -> bool {
for(std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> node_prop : node_var_data){ for(std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> node_prop : node_var_data){
std::stringstream name; std::stringstream name;
name << "node_" << n->description() << "_" << static_cast<char>(node_prop.first) << "_" << name_appendix; name << "node_" << n->description() << "_" << static_cast<char>(node_prop.first) << "_" << name_appendix;
node_lookup.insert({{n,node_prop.first}, p.add_variable(Variable(name.str(), std::get<0>(node_prop.second), std::get<1>(node_prop.second), std::get<2>(node_prop.second)))}); node_lookup.insert({{n,node_prop.first}, p.add_variable(Variable(name.str(), std::get<0>(node_prop.second), std::get<1>(node_prop.second), std::get<2>(node_prop.second)))});
} }
return true;
}; };
g.conditional_bfs_all_components( g.conditional_bfs_all_components(
......
...@@ -20,12 +20,14 @@ int main(){ ...@@ -20,12 +20,14 @@ int main(){
); );
while(true){ while(true){
system("killall graph_display");
Maintenance_Problem mp; Maintenance_Problem mp;
mpg >> mp; mpg >> mp;
std::ofstream ofs_graph("./.data/Maintenance_Problem/mp.netw"); std::ofstream ofs_graph("./.data/Maintenance_Problem/mp.netw");
ofs_graph << mp.network() << std::endl; ofs_graph << mp.network() << std::endl;
ofs_graph.close(); ofs_graph.close();
system("cd ../display/graph_display/ && (./graph_display --file ../../discrete_optimization_library/.data/Maintenance_Problem/mp.netw &) && cd ../../discrete_optimization_library");
std::ofstream ofs_program("./.data/Maintenance_Problem/mp.lp"); std::ofstream ofs_program("./.data/Maintenance_Problem/mp.lp");
ofs_program << mp << std::endl; ofs_program << mp << std::endl;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment