Commit b9beb5fb authored by Jonas Seidel's avatar Jonas Seidel

custom node and edge names & lp_generator now uses graph element names

parent fd879008
......@@ -8,6 +8,7 @@
#include <iostream>
#include <functional>
#include <queue>
#include <string>
#include "Edge.h"
#include "Node.h"
......@@ -26,11 +27,11 @@ public:
Graph(Graph<N,E>& graph);
Graph(Graph<N,E>&& graph);
Edge<N,E>* add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,Attribute> edge_attributes = {});
Edge<N,E>* add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,double> edge_attributes);
Edge<N,E>* add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,Attribute> edge_attributes = {}, std::string description = "");
Edge<N,E>* add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,double> edge_attributes = {}, std::string description = "");
Edge<N,E>* add_edge(Edge<N,E>* remote_edge, std::map<Node<N,E>*, Node<N,E>*>& node_lookup);
Node<N,E>* add_node(std::map<N,Attribute> node_attributes = {});
Node<N,E>* add_node(std::map<N,double> node_attributes);
Node<N,E>* add_node(std::map<N,Attribute> node_attributes = {}, std::string description = "");
Node<N,E>* add_node(std::map<N,double> node_attributes = {}, std::string description = "");
Node<N,E>* add_node(Node<N,E>* remote_node);
void remove_node(Node<N, E>* node);
......@@ -53,6 +54,10 @@ public:
void reset_attribute_values(std::set<E> edge_attr, std::set<N> node_attr = {});
std::pair<size_t, size_t> size(){
return {this->_nodes.size(), this->_edges.size()};
}
~Graph(){
while(this->nodes().begin() != this->nodes().end()){
this->remove_node(*this->nodes().begin());
......
......@@ -2,41 +2,45 @@ template <typename N, typename E>
Graph<N,E>::Graph(std::map<E,Attribute> default_values_edge_attributes, std::map<N,Attribute> default_values_node_attributes) : _template_node_attributes(default_values_node_attributes), _template_edge_attributes(default_values_edge_attributes){}
template <typename N, typename E>
Edge<N,E>* Graph<N,E>::add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,Attribute> edge_attributes){
Edge<N, E>* ptr = new Edge<N, E>(from, to, edge_attributes);
Edge<N,E>* Graph<N,E>::add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,Attribute> edge_attributes, std::string description){
Edge<N, E>* ptr = new Edge<N, E>(from, to, edge_attributes, description);
this->edges().insert(ptr);
return ptr;
}
template <typename N, typename E>
Edge<N,E>* Graph<N, E>::add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,double> edge_attributes){
Edge<N, E>* ptr = new Edge<N, E>(from, to, this->_template_edge_attributes, edge_attributes);
Edge<N,E>* Graph<N, E>::add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,double> edge_attributes, std::string description){
Edge<N, E>* ptr = new Edge<N, E>(from, to, this->_template_edge_attributes, edge_attributes, description);
this->edges().insert(ptr);
return ptr;
}
template <typename N, typename E>
Edge<N,E>* Graph<N,E>::add_edge(Edge<N,E>* remote_edge, std::map<Node<N,E>*, Node<N,E>*>& node_lookup){
return this->add_edge(node_lookup.find(remote_edge->from())->second, node_lookup.find(remote_edge->to())->second, remote_edge->attributes());
Edge<N, E>* ptr = new Edge<N, E>(*remote_edge, node_lookup);
this->edges().insert(ptr);
return ptr;
}
template <typename N, typename E>
Node<N,E>* Graph<N, E>::add_node(std::map<N,Attribute> node_attributes){
Node<N, E>* ptr = new Node<N, E>(node_attributes);
Node<N,E>* Graph<N, E>::add_node(std::map<N,Attribute> node_attributes, std::string description){
Node<N, E>* ptr = new Node<N, E>(node_attributes, description);
this->nodes().insert(ptr);
return ptr;
}
template <typename N, typename E>
Node<N,E>* Graph<N, E>::add_node(std::map<N,double> node_attributes){
Node<N, E>* ptr = new Node<N,E>(this->_template_node_attributes, node_attributes);
Node<N,E>* Graph<N, E>::add_node(std::map<N,double> node_attributes, std::string description){
Node<N, E>* ptr = new Node<N,E>(this->_template_node_attributes, node_attributes, description);
this->nodes().insert(ptr);
return ptr;
}
template <typename N, typename E>
Node<N,E>* Graph<N,E>::add_node(Node<N,E>* remote_node){
return this->add_node(remote_node->attributes());
Node<N, E>* ptr = new Node<N,E>(*remote_node);
this->nodes().insert(ptr);
return ptr;
}
template <typename N, typename E>
......
......@@ -6,25 +6,31 @@
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <string>
#include <sstream>
#include "Attribute.h"
template <typename E_N, typename E_E> class Node;
template <typename N, typename E> class Node;
template <typename E_N, typename E_E>
template <typename N, typename E>
class Edge{
Node<E_N, E_E>* _from;
Node<E_N, E_E>* _to;
std::string _description;
Node<N, E>* _from;
Node<N, E>* _to;
std::map<E_E, Attribute> _attributes;
std::map<E, Attribute> _attributes;
public:
Edge(Node<E_N, E_E>* from, Node<E_N, E_E>* to) : _from(from), _to(to){
Edge(Edge<N,E>& local_edge) : _description(local_edge._description), _from(local_edge._from), _to(local_edge._to), _attributes(local_edge._attributes) {}
Edge(Edge<N,E>& remote_edge, std::map<Node<N,E>*, Node<N,E>*>& node_lookup) : _description(remote_edge._description), _from(node_lookup.find(remote_edge._from)->second), _to(node_lookup.find(remote_edge._from)->second), _attributes(remote_edge._attributes) {}
Edge(Node<N, E>* from, Node<N, E>* to, std::string description = "") : _description(description), _from(from), _to(to){
from->add_incident(this);
to->add_incident(this);
};
Edge(Node<E_N, E_E>* from, Node<E_N, E_E>* to, std::map<E_E, Attribute>& default_attributes, std::map<E_E, double> attributes = {}) : _from(from), _to(to), _attributes(default_attributes){
for(std::pair<const E_E, double> pair : attributes){
Edge(Node<N, E>* from, Node<N, E>* to, std::map<E, Attribute>& default_attributes, std::map<E, double> attributes = {}, std::string description = "") : _description(description), _from(from), _to(to), _attributes(default_attributes){
for(std::pair<const E, double> pair : attributes){
this->attribute(pair.first).value() = pair.second;
}
......@@ -32,23 +38,32 @@ public:
to->add_incident(this);
};
Node<E_N, E_E>* from(){
std::string description(){
if(this->_description == ""){
std::stringstream name;
name << this;
return name.str();
}
return this->_description;
}
Node<N, E>* from(){
return this->_from;
}
Node<E_N, E_E>* to(){
Node<N, E>* to(){
return this->_to;
}
Node<E_N, E_E>* to(const Node<E_N, E_E>* node){
Node<N, E>* to(const Node<N, E>* node){
if(node != this->to() && node != this->from()) throw std::range_error("node not incident to edge");
return node == this->from() ? this->to() : this->from();
}
std::map<E_E, Attribute> attributes(){
std::map<E, Attribute> attributes(){
return this->_attributes;
}
Attribute& attribute(E_E key){
Attribute& attribute(E key){
return this->_attributes.find(key)->second;
}
......@@ -67,8 +82,8 @@ public:
}
};
template <typename E_N, typename E_E>
std::ostream& operator<<(std::ostream& os, Edge<E_N, E_E>& e);
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Edge<N, E>& e);
#include "Edge.ipp"
......
template <typename E_N, typename E_E>
std::ostream& operator<<(std::ostream& os, Edge<E_N, E_E>& e){
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Edge<N, E>& e){
os << "\033[0;32m";
os << "Edge " << &e << " (";
for(std::pair<E_E, Attribute> pair : e.attributes()){
os << "Edge " << e.description() << " (";
for(std::pair<E, Attribute> pair : e.attributes()){
os << pair.second.value() << ", ";
}
os << ") {" << e.from() << ", " << e.to() << "}";
os << ") {" << e.from()->description() << ", " << e.to()->description() << "}";
os << "\033[0m";
return os;
}
#include <cstddef>
#include <map>
#include <iostream>
#include <sstream>
#include "../Basic_Graph.h"
#include "../../Common/random_set_element_generator.h"
......
......@@ -91,7 +91,9 @@ std::pair<bool, std::pair<std::vector<Node<N,E>*>, std::vector<Edge<N,E>*>>> ran
added_edges.reserve(number_of_edges);
for(size_t i = 0; i < number_of_nodes; ++i){
added_nodes.push_back(g.add_node(node_attribute_generator.next()));
std::stringstream name;
name << g.size().first;
added_nodes.push_back(g.add_node(node_attribute_generator.next(), name.str()));
}
random_set_element_generator<Node<N,E>*> rand_stream (&g.nodes());
......@@ -116,7 +118,9 @@ std::pair<bool, std::pair<std::vector<Node<N,E>*>, std::vector<Edge<N,E>*>>> ran
goto redo;
}
added_edges.push_back(g.add_edge(n1, n2, edge_attribute_generator.next()));
std::stringstream name;
name << n1->description() << "_" << n2->description();
added_edges.push_back(g.add_edge(n1, n2, edge_attribute_generator.next(), name.str()));
}
return {true,{added_nodes, added_edges}};
......
......@@ -27,9 +27,13 @@ std::vector<Node<N,E>*> select_terminals(Graph<N,E>& g){
template <typename N, typename E>
Node<N,E>* tip_terminals(Graph<N,E>& g, random_attribute_generator<E>& edge_attribute_generator = random_attribute_generator<E>({}), random_attribute_generator<N>& node_attribute_generator = random_attribute_generator<N>({})){
std::vector<Node<N,E>*> terminals = select_terminals(g);
Node<N,E>* t = g.add_node(node_attribute_generator.next());
std::stringstream name;
name << g.size().first;
Node<N,E>* t = g.add_node(node_attribute_generator.next(), name.str());
for(Node<N,E>* n : terminals){
g.add_edge(n,t, edge_attribute_generator.next());
std::stringstream name;
name << n->description() << "_" << t->description();
g.add_edge(n, t, edge_attribute_generator.next(), name.str());
}
return t;
}
......@@ -60,9 +64,13 @@ std::vector<Node<N,E>*> select_sources(Graph<N,E>& g){
template <typename N, typename E>
Node<N,E>* tip_sources(Graph<N,E>& g, random_attribute_generator<E>& edge_attribute_generator = random_attribute_generator<E>({}), random_attribute_generator<N>& node_attribute_generator = random_attribute_generator<N>({})){
std::vector<Node<N,E>*> sources = select_sources(g);
Node<N,E>* s = g.add_node(node_attribute_generator.next());
std::stringstream name;
name << g.size().first;
Node<N,E>* s = g.add_node(node_attribute_generator.next(), name.str());
for(Node<N,E>* n : sources){
g.add_edge(s,n, edge_attribute_generator.next());
std::stringstream name;
name << s->description() << "_" << n->description();
g.add_edge(s, n, edge_attribute_generator.next(), name.str());
}
return s;
}
......
......@@ -9,35 +9,45 @@
#include "Attribute.h"
template <typename E_N, typename E_E> class Edge;
template <typename N, typename E> class Edge;
template <typename E_N, typename E_E>
template <typename N, typename E>
class Node{
std::set<Edge<E_N, E_E>*> _incident;
std::map<E_N, Attribute> _attributes;
std::string _description;
std::set<Edge<N, E>*> _incident;
std::map<N, Attribute> _attributes;
public:
Node(){}
Node(std::map<E_N, Attribute>& default_attributes, std::map<E_N,double> attributes = {}) : _attributes(default_attributes){
for(std::pair<const E_N, double> pair : attributes){
Node(std::map<N, Attribute>& default_attributes, std::map<N,double> attributes = {}, std::string description = "") : _description(description), _attributes(default_attributes){
for(std::pair<const N, double> pair : attributes){
this->attribute(pair.first).value() = pair.second;
}
}
std::set<Edge<E_N, E_E>*>& incident(){
std::string description(){
if(this->_description == ""){
std::stringstream name;
name << this;
return name.str();
}
return this->_description;
}
std::set<Edge<N, E>*>& incident(){
return this->_incident;
}
Edge<E_N, E_E>* add_incident(Edge<E_N,E_E>* edge){
Edge<N, E>* add_incident(Edge<N,E>* edge){
this->_incident.insert(edge);
return edge;
}
std::map<E_N, Attribute>& attributes(){
std::map<N, Attribute>& attributes(){
return this->_attributes;
}
Attribute& attribute(E_N key){
Attribute& attribute(N key){
return this->_attributes.find(key)->second;
}
......@@ -48,8 +58,8 @@ public:
}
};
template <typename E_N, typename E_E>
std::ostream& operator<<(std::ostream& os, Node<E_N, E_E>& n);
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Node<N, E>& n);
#include "Node.ipp"
......
template <typename E_N, typename E_E>
std::ostream& operator<<(std::ostream& os, Node<E_N, E_E>& n){
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Node<N, E>& n){
os << "\033[0;36m";
os << "Node " << &n << " { (";
for(std::pair<E_N, Attribute> pair : n.attributes()){
os << "Node " << n.description() << " { (";
for(std::pair<N, Attribute> pair : n.attributes()){
os << pair.second.value() << ", ";
}
os << ")\n \tEdges : {\n";
for(Edge<E_N, E_E>* e : n.incident()){
for(Edge<N, E>* e : n.incident()){
os << *e << "\n";
}
os << "\033[0;36m";
......
......@@ -31,7 +31,7 @@ double Constraint::rhs(){
}
std::ostream& operator<<(std::ostream& os, Constraint& constraint){
os << constraint.description() << ": ";
os << constraint.description() << ":\t";
bool empty = true;
bool add_plus = false;
......
......@@ -35,7 +35,8 @@ public:
Linear_Program& lp, Graph<N,E>& g,
edge_constraint_data_generator<N,E> edge_generator, node_constraint_data_generator<N,E> node_generator,
std::vector<std::pair<E, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > edge_var_data,
std::vector<std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > node_var_data
std::vector<std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > node_var_data,
std::string name_appendix
);
};
......
......@@ -19,7 +19,9 @@ std::map<Variable*, double> lp_generator::lhs_from_data(size_t start_index, size
template <typename N, typename E>
std::pair<std::map<std::pair<Node<N,E>*,N>, std::pair<Variable*, size_t>>, std::map<std::pair<Edge<N,E>*,E>, std::pair<Variable*, size_t>>> lp_generator::grow_from_graph(
Linear_Program& lp, Graph<N,E>& g, edge_constraint_data_generator<N,E> edge_generator, node_constraint_data_generator<N,E> node_generator,
std::vector<std::pair<E, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > edge_var_data, std::vector<std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > node_var_data)
std::vector<std::pair<E, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > edge_var_data, std::vector<std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> > node_var_data,
std::string name_appendix
)
{
Polyeder& p = lp.polyeder();
std::map<std::pair<Node<N,E>*,N>, std::pair<Variable*, size_t>> node_lookup;
......@@ -28,17 +30,17 @@ std::pair<std::map<std::pair<Node<N,E>*,N>, std::pair<Variable*, size_t>>, std::
size_t start_index = p.vs_dim();
// put inside conditional_bfs_all_components call as parameters;
std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_function = [&p, &edge_lookup, &edge_var_data, start_index](Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal) -> void {
std::function<void(Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal)> edge_function = [&p, &edge_lookup, &edge_var_data, start_index, name_appendix](Node<N,E>* from, Edge<N,E>* via, bool used_in_traversal) -> void {
for(std::pair<E, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> edge_prop : edge_var_data){
std::stringstream name;
name << "edge" << via->from() << "_" << via->to() << "_" << static_cast<char>(edge_prop.first);
name << "edge_" << via->description() << "_" << static_cast<char>(edge_prop.first) << "_" << name_appendix;
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](Node<N,E>* n) -> void {
std::function<void(Node<N,E>*)> node_function = [&p, &node_lookup, &node_var_data, start_index, name_appendix](Node<N,E>* n) -> void {
for(std::pair<N, std::tuple<integrality, std::pair<bool, double>, std::pair<bool, double>>> node_prop : node_var_data){
std::stringstream name;
name << "node" << n << "_" << static_cast<char>(node_prop.first);
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)))});
}
};
......
......@@ -55,7 +55,7 @@ Common := ./Common_Types/
Linear_Program_dep := Polyeder.o
Polyeder_dep := Constraint.o
Constraint_dep := Variable.o
maintenance_problem_generator_dep := Maintenance_Problem.o
maintenance_problem_generator_dep := Maintenance_Problem.o lp_generator.h lp_generator.ipp
Maintenance_Problem_crossdep := Linear_Programming/Linear_Program.o $(GRAPH_DEP)
$(GRAPH_OUT) $(LP_OUT) $(LP_PROBLEMS_OUT) $(COMMON_OUT): $$(patsubst %.o,%.cpp,$$@) $$(patsubst %.o,%.h,$$@) $$(addprefix $$(@D)/,$$($$(patsubst %.o,%_dep,$$(@F)))) $$($$(patsubst %.o,%_crossdep,$$(@F)))
$(CXX) $(CXXFLAGS) -c $(patsubst %.o, %.cpp, $@) -o $@
......
......@@ -21,14 +21,16 @@ Maintenance_Problem::Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* s
flow conservation constraints for all epochs
*/
for(size_t epoch = 0; epoch < intervals; ++epoch){
std::stringstream name_appendix;
name_appendix << "epoch_" << epoch;
lookup.push_back(lp_generator::grow_from_graph<CircSelectNodeFields, CircSelectEdgeFields>(
*this,
g,
[&critical, epoch](CircSelectEdge* edge) -> std::vector<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> {
std::stringstream capacity_name;
capacity_name << "edge_" << edge << "_capacity_epoch_" << epoch;
capacity_name << "edge_" << edge->description() << "_capacity_epoch_" << epoch;
std::stringstream non_critical_fix;
non_critical_fix << "edge_" << edge << "_non_critical_epoch_" << epoch;
non_critical_fix << "edge_" << edge->description() << "_non_critical_epoch_" << epoch;
std::vector<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> constraints;
if(critical.find(edge) == critical.end()){
......@@ -42,7 +44,7 @@ Maintenance_Problem::Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* s
[source, target, &critical, epoch](CircSelectNode* node) -> std::vector<constraint_data<CircSelectNodeFields, CircSelectEdgeFields>> {
if(node == source || node == target) return {};
std::stringstream name;
name << "node_" << node << "_flow_conservation_epoch_" << epoch;
name << "node_" << node->description() << "_flow_conservation_epoch_" << epoch;
lhs_constraint_data<CircSelectNodeFields, CircSelectEdgeFields> lhs = {{},{}};
for(CircSelectEdge* edge : node->incident()){
lhs.second.push_back({{edge,Flow}, (edge->to() == node ? 1 : -1) });
......@@ -50,7 +52,8 @@ Maintenance_Problem::Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* s
return {{name.str(), Equality, lhs, 0}};
},
{{Flow, {Integral, {true, 0}, {false, 0}}}, {Critical, {Integral, {true, 0}, {true, 1}}}},
{}
{},
name_appendix.str()
));
}
......@@ -63,7 +66,7 @@ Maintenance_Problem::Maintenance_Problem(CircSelectNetwork& g, CircSelectNode* s
lhs.insert({lookup_during_epoch.second.find({e, Critical})->second.first, 1});
}
std::stringstream name;
name << "critical_edge_" << e << "_processed";
name << "critical_edge_" << e->description() << "_processed";
this->polyeder().add_constraint(
{ // constraint
name.str(),
......
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