Commit 387640bb authored by Jonas Seidel's avatar Jonas Seidel
Browse files

using explicit template instantiation (and other methods) to increase build granularity

parent e2499d4b
......@@ -67,15 +67,15 @@ for (@$integral_indexes) {
#print "@$labels\n";
#print "@$restr_labels\n";
# calculating the wanted data:
print "Mixed Integer Convex Hull:\n";
my $mint_hull = mixed_integer_hull($import, $integral_indexes);
$mint_hull->COORDINATE_LABELS = $import->COORDINATE_LABELS;
print "Mixed Integer Convex Hull:\n";
print_constraints($mint_hull);
print "Integral Coordinate Projection Convex Hull\n";
my $proj = projection($import, $integral_indexes);
my $proj_hull = integer_hull($proj);
$proj_hull->COORDINATE_LABELS = $restr_labels;
print "Integral Coordinate Projection Convex Hull\n";
print_constraints($proj_hull);
#print "check: Integral Coordinate Projection of MI Convex Hull\n";
......
......@@ -3,6 +3,7 @@
#include "../Common/integrality.h"
enum opt_dir : int {max = 1, fix = 0, min = -1};
class Attribute{
......@@ -11,7 +12,7 @@ class Attribute{
integrality _integrality;
double _value;
public:
Attribute(opt_dir optimization_direction, double attribute, integrality integrality = Continuous);
Attribute(opt_dir optimization_direction = fix, double attribute = 0, integrality integrality = Continuous);
opt_dir& optimization_direction();
bool is_dependent();
......
#ifndef GRAPH_H
#define GRAPH_H
#include <set>
#include <map>
#include <vector>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <queue>
#include <string>
#include "Edge.h"
#include "Node.h"
template <typename N, typename E>
class Graph{
std::set<Edge<N, E>*> _edges;
std::set<Node<N, E>*> _nodes;
std::map<N,Attribute> _template_node_attributes;
std::map<E,Attribute> _template_edge_attributes;
public:
// TODO: use references to speed up constructors
Graph(){};
Graph(std::map<E,Attribute> default_values_edge_attributes, std::map<N,Attribute> default_values_node_attributes = {});
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 = {}, 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 = {}, 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);
void remove_edge(Edge<N, E>* edge);
// change to non reference return type?
std::set<Edge<N, E>*>& edges(){
return this->_edges;
}
std::set<Node<N, E>*>& nodes(){
return this->_nodes;
}
Attribute node_template(E attr){
return this->_templatNode_attributes.find(attr)->second;
}
Attribute edge_template(E attr){
return this->_template_edge_attributes.find(attr)->second;
}
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());
}
}
// _advanced.cpp:
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;});
// _special_members_and_operators:
void operator=(Graph<N,E>& graph);
void operator=(Graph<N,E>&& graph);
};
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Graph<N,E>& g);
#include "Basic_Graph.ipp"
#include "Basic_Graph_advanced.ipp"
#include "Basic_Graph_special_members_and_operators.ipp"
#endif
......@@ -23,7 +23,7 @@ class Edge{
public:
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);
......@@ -85,6 +85,5 @@ public:
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Edge<N, E>& e);
#include "Edge.ipp"
#endif
......@@ -26,6 +26,5 @@ public:
void operator>>(std::map<T,double>& var);
};
#include "random_attribute_generator.ipp"
#endif
#ifndef RANDOM_GRAPH_GENERATOR
#define RANDOM_GRAPH_GENERATOR
#include <cstddef>
#include <map>
#include <iostream>
#include <sstream>
#include "../Basic_Graph.h"
#include "../Graph.h"
#include "../../Common/random_set_element_generator.h"
#include "random_attribute_generator.h"
......@@ -28,4 +31,5 @@ public:
static std::pair<bool, std::pair<std::vector<Node<N,E>*>, std::vector<Edge<N,E>*>>> grow_random_acyclic(Graph<N, E>& g, size_t number_of_nodes, size_t number_of_edges, random_attribute_generator<E>& edge_attribute_generator, random_attribute_generator<N>& node_attribute_generator);
};
#include "random_graph_generator.ipp"
#endif
......@@ -4,8 +4,8 @@ random_graph_generator<N,E>::random_graph_generator(std::map<E,Attribute> defaul
template <typename N, typename E>
Graph<N,E> random_graph_generator<N,E>::next_acyclic(){
Graph<N,E> g (this->default_values_edge_attributes, this->default_values_edge_attributes);
while(!random_graph_generator::grow_random_acyclic(g, this->_number_of_nodes, this->_number_of_edges, this->_edge_generator, this->_node_generator)){
Graph<N,E> g (this->_default_values_edge_attributes, this->_default_values_node_attributes);
while(!random_graph_generator::grow_random_acyclic(g, this->_number_of_nodes, this->_number_of_edges, this->_edge_generator, this->_node_generator).first){
std::cout << "generation failed; retrying!" << std::endl;
}
return g;
......@@ -13,8 +13,8 @@ Graph<N,E> random_graph_generator<N,E>::next_acyclic(){
template <typename N, typename E>
Graph<N,E> random_graph_generator<N,E>::next(){
Graph<N,E> g (this->default_values_edge_attributes, this->default_values_edge_attributes);
while(!random_graph_generator::grow_random(g, this->_number_of_nodes, this->_number_of_edges, this->_edge_generator, this->_node_generator)){
Graph<N,E> g (this->_default_values_edge_attributes, this->_default_values_node_attributes);
while(!random_graph_generator::grow_random(g, this->_number_of_nodes, this->_number_of_edges, this->_edge_generator, this->_node_generator).first){
std::cout << "generation failed; retrying!" << std::endl;
}
return g;
......@@ -26,7 +26,7 @@ std::pair<std::pair<Node<N,E>*, Node<N,E>*>,Graph<N,E>> random_graph_generator<N
while(!random_graph_generator::grow_random_acyclic(g, this->_number_of_nodes, this->_number_of_edges, this->_edge_generator, this->_node_generator).first){
std::cout << "generation failed; retrying!" << std::endl;
}
auto tips = tip_fringes(g, this->_edge_generator, this->_node_generator);
auto tips = g.tip_fringes(this->_edge_generator, this->_node_generator);
return {tips, std::move(g)};
}
......@@ -59,7 +59,7 @@ std::pair<bool, std::pair<std::vector<Node<N,E>*>, std::vector<Edge<N,E>*>>> ran
}
{
auto existing_path = directed_admissible_st_path(g, n1, n2);
auto existing_path = Path<N,E>::directed_admissible_st_path(n1, n2);
if(existing_path.first && existing_path.second.number_of_edges() <= 1) {
attempt++;
goto redo;
......@@ -113,7 +113,7 @@ std::pair<bool, std::pair<std::vector<Node<N,E>*>, std::vector<Edge<N,E>*>>> ran
goto failed;
}
if(n1 == n2 || directed_admissible_st_path(g, n2, n1).first || directed_admissible_st_path(g, n1, n2).second.number_of_edges() == 1) {
if(n1 == n2 || Path<N,E>::directed_admissible_st_path(n2, n1).first || Path<N,E>::directed_admissible_st_path(n1, n2).second.number_of_edges() == 1) {
attempt++;
goto redo;
}
......
#ifndef GRAPH_EXPORT
#define GRAPH_EXPORT
#ifndef GRAPH_H
#define GRAPH_H
#include "Basic_Graph.h"
#include <set>
#include <map>
#include <vector>
#include <initializer_list>
#include <iostream>
#include <functional>
#include <queue>
#include <string>
#include "Edge.h"
#include "Node.h"
#include "Path.h"
#include "Graph_Operations/path_operations.ipp"
#include "Graph_Operations/fringe_graph_operations.ipp"
#include "Graph_Operations/flow_algorithms.ipp"
#include "Generators/random_attribute_generator.h"
template <typename N, typename E> class Graph;
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Graph<N,E>& g);
template <typename N, typename E>
class Graph{
std::set<Edge<N, E>*> _edges;
std::set<Node<N, E>*> _nodes;
std::map<N,Attribute> _template_node_attributes;
std::map<E,Attribute> _template_edge_attributes;
public:
// TODO: use references to speed up constructors
Graph(){};
Graph(std::map<E,Attribute> default_values_edge_attributes, std::map<N,Attribute> default_values_node_attributes = {});
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 = {}, 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 = {}, 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);
void remove_edge(Edge<N, E>* edge);
// change to non reference return type?
std::set<Edge<N, E>*>& edges(){
return this->_edges;
}
std::set<Node<N, E>*>& nodes(){
return this->_nodes;
}
Attribute node_template(N attr){
return this->_template_node_attributes.find(attr)->second;
}
Attribute edge_template(E attr){
return this->_template_edge_attributes.find(attr)->second;
}
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());
}
}
// _advanced.cpp:
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;}
);
// _selections.cpp;
// finges
std::vector<Node<N,E>*> select_terminals();
Node<N,E>* tip_terminals(
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>*> select_sources();
Node<N,E>* tip_sources(
random_attribute_generator<E>& edge_attribute_generator = random_attribute_generator<E>({}),
random_attribute_generator<N>& node_attribute_generator = random_attribute_generator<N>({})
);
std::pair<Node<N,E>*, Node<N,E>*> tip_fringes(
random_attribute_generator<E>& edge_attribute_generator = random_attribute_generator<E>({}),
random_attribute_generator<N>& node_attribute_generator = random_attribute_generator<N>({})
);
// _flow_alg.ipp
double ford_fulkerson(Node<N,E>* s, Node<N,E>* t, E opt_attr, E lower_limit_attr, E upper_limit_attr);
// _special_members_and_operators:
void operator=(Graph<N,E>& graph);
void operator=(Graph<N,E>&& graph);
// io:
friend std::ostream& operator<< <N,E>(std::ostream& os, Graph<N,E>& g);
};
#endif
template <typename N, typename E>
double ford_fulkerson(Graph<N,E>& g, Node<N,E>* s, Node<N,E>* t, E opt_attr, E lower_limit_attr, E upper_limit_attr){
double value;
while(true){
auto path = directed_admissible_st_path(g, s,t, opt_attr, lower_limit_attr, upper_limit_attr);
if(!path.first) break;
value += augment_edges_along_path(path.second, opt_attr, lower_limit_attr, upper_limit_attr);
}
return value;
}
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){
/*
......
......@@ -2,8 +2,8 @@ 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, std::string description){
Edge<N, E>* ptr = new Edge<N, E>(from, to, edge_attributes, description);
Edge<N,E>* Graph<N,E>::add_edge(Node<N, E>* from, Node<N, E>* to, std::map<E,Attribute> edge_attributes_ignore_defaults, std::string description){
Edge<N, E>* ptr = new Edge<N, E>(from, to, edge_attributes_ignore_defaults, {}, description);
this->edges().insert(ptr);
return ptr;
}
......@@ -23,8 +23,8 @@ Edge<N,E>* Graph<N,E>::add_edge(Edge<N,E>* remote_edge, std::map<Node<N,E>*, Nod
}
template <typename N, typename E>
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);
Node<N,E>* Graph<N, E>::add_node(std::map<N,Attribute> node_attributes_ignore_defaults, std::string description){
Node<N, E>* ptr = new Node<N, E>(node_attributes_ignore_defaults, {}, description);
this->nodes().insert(ptr);
return ptr;
}
......
template <typename N, typename E>
double Graph<N,E>::ford_fulkerson(Node<N,E>* s, Node<N,E>* t, E opt_attr, E lower_limit_attr, E upper_limit_attr){
double value;
while(true){
auto path = Path<N,E>::directed_admissible_st_path(s,t, opt_attr, lower_limit_attr, upper_limit_attr);
if(!path.first) break;
value += path.second.augment_edges_along_path(this->edge_template(opt_attr).optimization_direction(), opt_attr, lower_limit_attr, upper_limit_attr);
}
return value;
}
#include <vector>
#include "../Generators/random_attribute_generator.h"
#include "Generators/random_attribute_generator.h"
/*
terminals
*/
template <typename N, typename E>
bool is_terminal(Node<N,E>* node){
for(Edge<N,E>* e : node->incident()){
if(node == e->from()) return false;
}
return true;
}
template <typename N, typename E>
std::vector<Node<N,E>*> select_terminals(Graph<N,E>& g){
std::vector<Node<N,E>*> Graph<N,E>::select_terminals(){
std::vector<Node<N,E>*> terminals;
for(Node<N,E>* n : g.nodes()){
if(is_terminal(n)){
for(Node<N,E>* n : this->_nodes){
if(n->is_terminal()){
terminals.push_back(n);
}
}
......@@ -25,36 +18,31 @@ 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>* Graph<N,E>::tip_terminals(
random_attribute_generator<E>& edge_attribute_generator,
random_attribute_generator<N>& node_attribute_generator
){
std::vector<Node<N,E>*> terminals = this->select_terminals();
std::stringstream name;
name << g.size().first;
Node<N,E>* t = g.add_node(node_attribute_generator.next(), name.str());
name << this->size().first;
Node<N,E>* t = this->add_node(node_attribute_generator.next(), name.str());
for(Node<N,E>* n : terminals){
std::stringstream name;
name << n->description() << "_" << t->description();
g.add_edge(n, t, edge_attribute_generator.next(), name.str());
this->add_edge(n, t, edge_attribute_generator.next(), name.str());
}
return t;
}
/*
sources
*/
template <typename N, typename E>
bool is_source(Node<N,E>* node){
for(Edge<N,E>* e : node->incident()){
if(node == e->to()) return false;
}
return true;
}
template <typename N, typename E>
std::vector<Node<N,E>*> select_sources(Graph<N,E>& g){
std::vector<Node<N,E>*> Graph<N,E>::select_sources(){
std::vector<Node<N,E>*> sources;
for(Node<N,E>* n : g.nodes()){
if(is_source(n)){
for(Node<N,E>* n : this->nodes()){
if(n->is_source()){
sources.push_back(n);
}
}
......@@ -62,27 +50,33 @@ 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>* Graph<N,E>::tip_sources(
random_attribute_generator<E>& edge_attribute_generator,
random_attribute_generator<N>& node_attribute_generator
){
std::vector<Node<N,E>*> sources = this->select_sources();
std::stringstream name;
name << g.size().first;
Node<N,E>* s = g.add_node(node_attribute_generator.next(), name.str());
name << this->size().first;
Node<N,E>* s = this->add_node(node_attribute_generator.next(), name.str());
for(Node<N,E>* n : sources){
std::stringstream name;
name << s->description() << "_" << n->description();
g.add_edge(s, n, edge_attribute_generator.next(), name.str());
this->add_edge(s, n, edge_attribute_generator.next(), name.str());
}
return s;
}
/*
tandem
*/
template <typename N, typename E>
std::pair<Node<N,E>*, Node<N,E>*> tip_fringes(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::pair<Node<N,E>*, Node<N,E>*> Graph<N,E>::tip_fringes(
random_attribute_generator<E>& edge_attribute_generator,
random_attribute_generator<N>& node_attribute_generator
){
std::pair<Node<N,E>*, Node<N,E>*> tips;
tips.first = tip_sources(g, edge_attribute_generator, node_attribute_generator);
tips.second = tip_terminals(g, edge_attribute_generator, node_attribute_generator);
tips.first = this->tip_sources(edge_attribute_generator, node_attribute_generator);
tips.second = this->tip_terminals(edge_attribute_generator, node_attribute_generator);
return tips;
}
#ifndef GRAPH_EXPORT
#define GRAPH_EXPORT
#include "Graph.h"
#include "Generators/random_attribute_generator.h"
#include "Generators/random_graph_generator.h"
#endif
#include "Graphtheory.h"
#include "Edge.ipp"
#include "Node.ipp"
#include "Path.ipp"
#include "Path_dops.ipp"
#include "Graph_basics.ipp"
#include "Graph_advanced.ipp"
#include "Graph_special_members_and_operators.ipp"
#include "Graph_selections.ipp"
#include "Graph_flow_alg.ipp"
#include "Generators/random_attribute_generator.ipp"
#include "Generators/random_graph_generator.ipp"
......@@ -56,11 +56,18 @@ public:
delete *this->incident().begin();
}
}
/*
derived properties
*/
bool is_source();
bool is_terminal();
};
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Node<N, E>& n);
#include "Node.ipp"
#endif
template <typename N, typename E>
bool Node<N,E>::is_source(){
for(Edge<N,E>* e : this->incident()){
if(this == e->to()) return false;
}
return true;
}
template <typename N, typename E>
bool Node<N,E>::is_terminal(){
for(Edge<N,E>* e : this->incident()){
if(this == e->from()) return false;
}
return true;
}
template <typename N, typename E>
std::ostream& operator<<(std::ostream& os, Node<N, E>& n){
os << "\033[0;36m";
......
......@@ -6,19 +6,17 @@
#include <list>
#include <iostream>
template <typename N, typename E>
class Graph;
template <typename N, typename E>