Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Bachelorarbeit
Discrete Optimization Library
Commits
16b3fcfb
Commit
16b3fcfb
authored
Jan 23, 2021
by
jonasseidel
Browse files
more const correctness and an overhaul of the path data structure
parent
e31b2f71
Changes
16
Hide whitespace changes
Inline
Side-by-side
Graphtheory/Edge.cpp
View file @
16b3fcfb
#include "Edge.h"
Edge
::
Edge
(
const
Edge
&
remote_edge
,
const
std
::
map
<
Node
*
,
Node
*>&
node_lookup
)
:
_description
(
remote_edge
.
_description
),
_from
(
node_lookup
.
find
(
remote_edge
.
_from
)
->
second
),
_to
(
node_lookup
.
find
(
remote_edge
.
_to
)
->
second
),
_attributes
(
remote_edge
.
_attributes
)
{
Edge
::
Edge
(
const
Edge
&
remote_edge
,
const
std
::
map
<
const
Node
*
,
Node
*>&
node_lookup
)
:
_description
(
remote_edge
.
_description
),
_from
(
node_lookup
.
find
(
remote_edge
.
_from
)
->
second
),
_to
(
node_lookup
.
find
(
remote_edge
.
_to
)
->
second
),
_attributes
(
remote_edge
.
_attributes
)
{
this
->
_from
->
add_incident
(
this
);
this
->
_to
->
add_incident
(
this
);
}
...
...
@@ -50,7 +50,7 @@ void Edge::reconnect(){
this
->
to
()
->
incident
().
insert
(
this
);
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Edge
&
e
){
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Edge
&
e
){
if
(
&
os
==
&
std
::
cout
){
os
<<
"
\033
[0;32m"
;
os
<<
"Edge "
<<
e
.
description
()
<<
" ( "
;
...
...
Graphtheory/Edge.h
View file @
16b3fcfb
...
...
@@ -24,7 +24,7 @@ class Edge{
public:
Edge
(
const
Edge
&
local_edge
)
:
_description
(
local_edge
.
_description
),
_from
(
local_edge
.
_from
),
_to
(
local_edge
.
_to
),
_attributes
(
local_edge
.
_attributes
)
{}
Edge
(
Edge
&&
local_edge
)
:
_description
(
std
::
move
(
local_edge
.
_description
)),
_from
(
std
::
move
(
local_edge
.
_from
)),
_to
(
std
::
move
(
local_edge
.
_to
)),
_attributes
(
std
::
move
(
local_edge
.
_attributes
))
{}
Edge
(
const
Edge
&
remote_edge
,
const
std
::
map
<
Node
*
,
Node
*>&
node_lookup
);
Edge
(
const
Edge
&
remote_edge
,
const
std
::
map
<
const
Node
*
,
Node
*>&
node_lookup
);
Edge
(
Node
*
from
,
Node
*
to
,
std
::
string
description
,
std
::
map
<
std
::
string
,
Attribute
>
attributes
=
{});
Edge
(
std
::
istream
&
is
,
const
std
::
map
<
std
::
string
,
Node
*
>&
name_lookup
);
...
...
@@ -37,21 +37,21 @@ public:
return
this
->
_description
;
}
Node
*
const
&
from
()
const
{
Node
*
from
()
const
{
return
this
->
_from
;
}
Node
*&
from
()
{
return
this
->
_from
;
}
Node
*
const
&
to
()
const
{
Node
*
to
()
const
{
return
this
->
_to
;
}
Node
*&
to
()
{
return
this
->
_to
;
}
Node
*
const
&
to
(
const
Node
*
node
)
const
{
Node
*
to
(
const
Node
*
node
)
const
{
if
(
node
!=
this
->
to
()
&&
node
!=
this
->
from
())
throw
std
::
range_error
(
"node not incident to edge"
);
return
node
==
this
->
from
()
?
this
->
to
()
:
this
->
from
();
}
...
...
@@ -63,6 +63,7 @@ public:
const
std
::
map
<
std
::
string
,
Attribute
>&
attributes
()
const
{
return
this
->
_attributes
;
}
std
::
map
<
std
::
string
,
Attribute
>&
attributes
()
{
return
this
->
_attributes
;
}
...
...
@@ -85,6 +86,16 @@ public:
return
search
->
second
;
}
const
Attribute
&
attribute_throwing
(
const
std
::
string
&
attr
)
const
{
auto
search
=
this
->
_attributes
.
find
(
attr
);
if
(
search
==
this
->
_attributes
.
end
()){
std
::
stringstream
text
;
text
<<
"
\"
"
<<
attr
<<
"
\"
is not defined for Node "
<<
this
->
description
();
throw
std
::
range_error
(
text
.
str
());
}
return
search
->
second
;
}
void
disconnect
();
void
reconnect
();
...
...
@@ -109,6 +120,6 @@ public:
void
dump
();
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Edge
&
e
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Edge
&
e
);
#endif
Graphtheory/Generators/random_graph_generator.cpp
View file @
16b3fcfb
...
...
@@ -30,8 +30,12 @@ std::pair<std::pair<Node*, Node*>,Graph> random_graph_generator::next_acyclic_2_
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
=
g
.
tip_fringes
(
this
->
_edge_generator
,
this
->
_node_generator
);
return
{
tips
,
std
::
move
(
g
)};
auto
[
source
,
target
]
=
g
.
tip_fringes
(
this
->
_edge_generator
,
this
->
_node_generator
);
source
->
add_attribute
(
"Source"
,
Attribute
({
fix
,
1
,
Integral
})
);
target
->
add_attribute
(
"Target"
,
Attribute
({
fix
,
1
,
Integral
})
);
return
{{
source
,
target
},
std
::
move
(
g
)};
}
std
::
pair
<
std
::
pair
<
Node
*
,
Node
*>
,
Graph
>
random_graph_generator
::
next_acyclic_in_steps_2_tips
(
size_t
steps
,
size_t
fading
){
...
...
@@ -39,8 +43,12 @@ std::pair<std::pair<Node*, Node*>, Graph> random_graph_generator::next_acyclic_i
while
(
!
random_graph_generator
::
grow_random_acyclic_in_steps
(
g
,
this
->
_number_of_nodes
/
steps
,
this
->
_number_of_edges
/
steps
,
steps
,
fading
,
this
->
_edge_generator
,
this
->
_node_generator
).
first
){
std
::
cout
<<
"generation failed; retrying!"
<<
std
::
endl
;
}
auto
tips
=
g
.
tip_fringes
(
this
->
_edge_generator
,
this
->
_node_generator
);
return
{
tips
,
std
::
move
(
g
)};
auto
[
source
,
target
]
=
g
.
tip_fringes
(
this
->
_edge_generator
,
this
->
_node_generator
);
source
->
add_attribute
(
"Source"
,
Attribute
({
fix
,
1
,
Integral
})
);
target
->
add_attribute
(
"Target"
,
Attribute
({
fix
,
1
,
Integral
})
);
return
{{
source
,
target
},
std
::
move
(
g
)};
}
...
...
Graphtheory/Graph.h
View file @
16b3fcfb
...
...
@@ -37,10 +37,10 @@ public:
Graph
(
Graph
&
graph
);
Graph
(
Graph
&&
graph
);
Edge
*
const
add_edge
(
Node
*
from
,
Node
*
to
,
const
std
::
string
&
description
,
const
std
::
map
<
std
::
string
,
Attribute
>&
edge_attributes
=
{});
Edge
*
const
add_edge
(
Edge
*
remote_edge
,
const
std
::
map
<
Node
*
,
Node
*>&
node_lookup
);
Node
*
const
add_node
(
std
::
string
description
,
const
std
::
map
<
std
::
string
,
Attribute
>&
node_attributes
=
{});
Node
*
const
add_node
(
Node
*
remote_node
);
Edge
*
add_edge
(
Node
*
from
,
Node
*
to
,
const
std
::
string
&
description
,
const
std
::
map
<
std
::
string
,
Attribute
>&
edge_attributes
=
{});
Edge
*
add_edge
(
const
Edge
*
remote_edge
,
const
std
::
map
<
const
Node
*
,
Node
*>&
node_lookup
);
Node
*
add_node
(
std
::
string
description
,
const
std
::
map
<
std
::
string
,
Attribute
>&
node_attributes
=
{});
Node
*
add_node
(
const
Node
*
remote_node
);
void
remove_node
(
Node
*
node
);
void
remove_edge
(
Edge
*
edge
);
...
...
@@ -53,7 +53,14 @@ public:
return
this
->
_nodes
;
}
std
::
pair
<
bool
,
Attribute
>
node_template
(
const
std
::
string
&
attr
)
const
{
std
::
set
<
const
Edge
*>
edges
()
const
{
return
std
::
set
<
const
Edge
*>
(
this
->
_edges
.
begin
(),
this
->
_edges
.
end
());
}
std
::
set
<
const
Node
*>
nodes
()
const
{
return
std
::
set
<
const
Node
*>
(
this
->
_nodes
.
begin
(),
this
->
_nodes
.
end
());
}
std
::
pair
<
bool
,
Attribute
>
node_template
(
const
std
::
string
&
attr
)
const
{
// TODO: change to returning iterator to support external manipulation and proper const functions
auto
search
=
this
->
_template_node_attributes
.
find
(
attr
);
if
(
search
==
this
->
_template_node_attributes
.
end
()){
return
{
false
,
{
fix
,
0
}};
...
...
@@ -69,7 +76,27 @@ public:
return
{
true
,
search
->
second
};
}
Attribute
edge_template_throwing
(
const
std
::
string
&
attr
){
Attribute
&
edge_template_throwing
(
const
std
::
string
&
attr
){
auto
search
=
this
->
_template_edge_attributes
.
find
(
attr
);
if
(
search
==
this
->
_template_edge_attributes
.
end
()){
std
::
stringstream
text
;
text
<<
"
\"
"
<<
attr
<<
"
\"
is not defined by default for Edges in used Graph"
;
throw
std
::
range_error
(
text
.
str
());
}
return
search
->
second
;
}
Attribute
&
node_template_throwing
(
const
std
::
string
&
attr
){
auto
search
=
this
->
_template_node_attributes
.
find
(
attr
);
if
(
search
==
this
->
_template_node_attributes
.
end
()){
std
::
stringstream
text
;
text
<<
"
\"
"
<<
attr
<<
"
\"
is not defined by default for Nodes in used Graph"
;
throw
std
::
range_error
(
text
.
str
());
}
return
search
->
second
;
}
const
Attribute
&
edge_template_throwing
(
const
std
::
string
&
attr
)
const
{
auto
search
=
this
->
_template_edge_attributes
.
find
(
attr
);
if
(
search
==
this
->
_template_edge_attributes
.
end
()){
std
::
stringstream
text
;
...
...
@@ -79,7 +106,7 @@ public:
return
search
->
second
;
}
Attribute
node_template_throwing
(
const
std
::
string
&
attr
){
const
Attribute
&
node_template_throwing
(
const
std
::
string
&
attr
)
const
{
auto
search
=
this
->
_template_node_attributes
.
find
(
attr
);
if
(
search
==
this
->
_template_node_attributes
.
end
()){
std
::
stringstream
text
;
...
...
@@ -106,6 +133,10 @@ public:
Node
*
s
,
Node
*
t
,
std
::
function
<
bool
(
Node
*
from
,
Edge
*
via
)
>
guide
=
[](
Node
*
n
,
Edge
*
e
)
->
bool
{
return
e
->
from
()
==
n
;}
);
std
::
pair
<
bool
,
const
Path
>
directed_admissible_st_path
(
const
Node
*
s
,
const
Node
*
t
,
std
::
function
<
bool
(
const
Node
*
from
,
const
Edge
*
via
)
>
guide
=
[](
const
Node
*
n
,
const
Edge
*
e
)
->
bool
{
return
e
->
from
()
==
n
;}
)
const
;
std
::
pair
<
bool
,
Path
>
directed_admissible_st_path
(
Node
*
s
,
Node
*
t
,
std
::
string
opt_attr
,
...
...
@@ -116,15 +147,19 @@ public:
// _select_opertations
std
::
set
<
Edge
*>
gather_edges
(
std
::
vector
<
std
::
string
>
attributes
);
std
::
set
<
Node
*>
gather_nodes
(
std
::
vector
<
std
::
string
>
attributes
);
std
::
set
<
const
Edge
*>
gather_edges
(
std
::
vector
<
std
::
string
>
attributes
)
const
;
std
::
set
<
const
Node
*>
gather_nodes
(
std
::
vector
<
std
::
string
>
attributes
)
const
;
// fringe_operations
std
::
vector
<
Node
*>
select_targets
();
std
::
vector
<
const
Node
*>
select_targets
()
const
;
Node
*
tip_targets
(
random_attribute_generator
edge_attribute_generator
=
{{}},
random_attribute_generator
node_attribute_generator
=
{{}}
);
std
::
vector
<
Node
*>
select_sources
();
std
::
vector
<
const
Node
*>
select_sources
()
const
;
Node
*
tip_sources
(
random_attribute_generator
edge_attribute_generator
=
{{}},
random_attribute_generator
node_attribute_generator
=
{{}}
...
...
@@ -140,6 +175,14 @@ public:
bool
all_paths
=
false
,
std
::
function
<
bool
(
Node
*
from
,
Edge
*
via
)
>
guide
=
[](
Node
*
n
,
Edge
*
e
)
->
bool
{
return
e
->
from
()
==
n
;}
);
void
conditional_bfs_all_components
(
std
::
function
<
void
(
const
Node
*
from
,
const
Edge
*
via
,
bool
used_in_traversal
)
>
edge_exec
,
std
::
function
<
bool
(
const
Edge
*
via
,
const
Node
*
node
)
>
node_exec
,
std
::
deque
<
const
Node
*>
starting_nodes
=
{},
bool
all_paths
=
false
,
std
::
function
<
bool
(
const
Node
*
from
,
const
Edge
*
via
)
>
guide
=
[](
const
Node
*
n
,
const
Edge
*
e
)
->
bool
{
return
e
->
from
()
==
n
;}
)
const
;
// _flow_algorithms.cpp:
double
ford_fulkerson
(
Node
*
s
,
Node
*
t
,
std
::
string
opt_attr
,
std
::
string
lower_limit_attr
,
std
::
string
upper_limit_attr
);
...
...
@@ -147,19 +190,19 @@ public:
// _special_members_and_operators:
void
operator
=
(
const
Graph
&
graph
);
std
::
pair
<
Graph
,
std
::
map
<
Node
*
,
Node
*>
>
copy_ret_lookup
()
const
;
std
::
pair
<
Graph
,
std
::
map
<
const
Node
*
,
Node
*>
>
copy_ret_lookup
()
const
;
void
operator
=
(
Graph
&&
graph
);
// _debug_helpers (Graph.ipp)
void
dump
();
// friendships:
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Graph
&
g
);
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Graph
&
g
);
friend
std
::
istream
&
operator
>>
(
std
::
istream
&
is
,
Graph
&
g
);
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Graph
&
g
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Graph
&
g
);
std
::
istream
&
operator
>>
(
std
::
istream
&
is
,
Graph
&
g
);
...
...
Graphtheory/Graph.ipp
View file @
16b3fcfb
Graph::Graph(std::map<std::string, Attribute> default_values_edge_attributes, std::map<std::string, Attribute> default_values_node_attributes) : _template_node_attributes(std::move(default_values_node_attributes)), _template_edge_attributes(std::move(default_values_edge_attributes)){}
Edge*
const
Graph::add_edge(Node* from, Node* to, const std::string& description, const std::map<std::string, Attribute>& edge_attributes){
Edge* Graph::add_edge(Node* from, Node* to, const std::string& description, const std::map<std::string, Attribute>& edge_attributes){
std::map<std::string, Attribute> unified_attr = this->_template_edge_attributes;
for(std::pair<std::string, Attribute> overriding_attr : edge_attributes){
auto new_or_not = unified_attr.insert(overriding_attr);
...
...
@@ -9,18 +9,18 @@ Edge* const Graph::add_edge(Node* from, Node* to, const std::string& description
}
}
Edge*
const
ptr = new Edge(from, to, description, unified_attr);
Edge* ptr = new Edge(from, to, description, unified_attr);
this->edges().insert(ptr);
return ptr;
}
Edge*
const
Graph::add_edge(Edge* remote_edge, const std::map<Node*, Node*>& node_lookup){
Edge*
const
ptr = new Edge(*remote_edge, node_lookup);
Edge* Graph::add_edge(
const
Edge* remote_edge, const std::map<
const
Node*, Node*>& node_lookup){
Edge* ptr = new Edge(*remote_edge, node_lookup);
this->edges().insert(ptr);
return ptr;
}
Node*
const
Graph::add_node(std::string description, const std::map<std::string, Attribute>& node_attributes){
Node* Graph::add_node(std::string description, const std::map<std::string, Attribute>& node_attributes){
std::map<std::string, Attribute> unified_attr = this->_template_node_attributes;
for(std::pair<std::string, Attribute> overriding_attr : node_attributes){
auto new_or_not = unified_attr.insert(overriding_attr);
...
...
@@ -29,13 +29,13 @@ Node* const Graph::add_node(std::string description, const std::map<std::string,
}
}
Node*
const
ptr = new Node(description, unified_attr);
Node* ptr = new Node(description, unified_attr);
this->nodes().insert(ptr);
return ptr;
}
Node*
const
Graph::add_node(Node* remote_node){
Node*
const
ptr = new Node(*remote_node);
Node* Graph::add_node(
const
Node* remote_node){
Node* ptr = new Node(*remote_node);
this->nodes().insert(ptr);
return ptr;
}
...
...
@@ -67,16 +67,16 @@ void Graph::reset_attribute_values(const std::set<std::string>& edge_attr, const
}
}
std::ostream& operator<<(std::ostream& os, Graph& g){
std::ostream& operator<<(std::ostream& os,
const
Graph& g){
if(&os == &std::cout){
os << "\033[0;31m";
os << "Graph { Nodes { \n";
for(Node* n : g.nodes()){
for(
const
Node* n : g.nodes()){
os << *n << "\n";
}
os << "\033[0;31m";
os << "} Edges {" << "\n";
for(Edge* e : g.edges()){
for(
const
Edge* e : g.edges()){
os << *e << "\n";
}
os << "\033[0;31m";
...
...
@@ -84,11 +84,11 @@ std::ostream& operator<<(std::ostream& os, Graph& g){
os << "\033[0m";
}else{
os << "Graph { Nodes { \n";
for(Node* n : g.nodes()){
for(
const
Node* n : g.nodes()){
os << *n << "\n";
}
os << "} Edges {" << "\n";
for(Edge* e : g.edges()){
for(
const
Edge* e : g.edges()){
os << *e << "\n";
}
os << "} \nNode_Defaults { ";
...
...
Graphtheory/Graph_advanced.ipp
View file @
16b3fcfb
...
...
@@ -112,3 +112,55 @@ void Graph::conditional_bfs_all_components(
}
}
}
void Graph::conditional_bfs_all_components(
std::function<void(const Node* from, const Edge* via, bool used_in_traversal)> edge_exec,
std::function<bool(const Edge* via, const Node* node)> node_exec,
std::deque<const Node*> starting_nodes,
bool all_paths,
std::function<bool(const Node* from, const Edge* via)> guide
) const {
/*
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 !!
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
if node_exec returns true traversal over its incident edges will be forced no matter their visitation status
*/
std::set<const Node*> uncharted = this->nodes();
std::deque<std::pair<const Edge*, const Node*>> active;
for(const Node* node : starting_nodes){
active.push_back({nullptr, node});
}
while(!uncharted.empty()){
if(active.empty()){
active.push_back({nullptr, *uncharted.begin()});
uncharted.erase(*uncharted.begin());
}
while(!active.empty()){
std::pair<const Edge*, const Node*> next = active.front(); active.pop_front();
bool local_all_paths = node_exec(next.first, next.second);
const Node* n = next.second;
for(const Edge* e : n->incident()){
bool used_in_traversal = false;
if(guide(n, e)){
if(uncharted.find(e->to(n)) != uncharted.end() || all_paths || local_all_paths) {
used_in_traversal = true;
active.push_back({e, e->to(n)});
uncharted.erase(e->to(n));
}
edge_exec(n, e, used_in_traversal);
}
}
}
}
}
Graphtheory/Graph_fringe_operations.ipp
View file @
16b3fcfb
...
...
@@ -2,10 +2,28 @@
targets
*/
std::vector<Node*> Graph::select_targets(){
std::vector<Node*> Graph::select_targets(){
// TODO: rename to terminal / extreme or similar
std::vector<Node*> targets;
for(Node* n : this->nodes()){
if(n->is_target()){
for(Node* n : this->_nodes){
bool is_terminal_target = true;
for(Edge* e : n->incident()){
if(n == e->from()) is_terminal_target = false;
}
if(is_terminal_target){
targets.push_back(n);
}
}
return targets;
}
std::vector<const Node*> Graph::select_targets() const {
std::vector<const Node*> targets;
for(Node* n : this->_nodes){
bool is_terminal_target = true;
for(Edge* e : n->incident()){
if(n == e->from()) is_terminal_target = false;
}
if(is_terminal_target){
targets.push_back(n);
}
}
...
...
@@ -42,8 +60,26 @@ Node* Graph::tip_targets(random_attribute_generator edge_attribute_generator, ra
std::vector<Node*> Graph::select_sources(){
std::vector<Node*> sources;
for(Node* n : this->nodes()){
if(n->is_source()){
for(Node* n : this->_nodes){
bool is_terminal_source = true;
for(Edge* e : n->incident()){
if(n == e->to()) is_terminal_source = false;
}
if(is_terminal_source){
sources.push_back(n);
}
}
return sources;
}
std::vector<const Node*> Graph::select_sources() const {
std::vector<const Node*> sources;
for(Node* n : this->_nodes){
bool is_terminal_source = true;
for(Edge* e : n->incident()){
if(n == e->to()) is_terminal_source = false;
}
if(is_terminal_source){
sources.push_back(n);
}
}
...
...
Graphtheory/Graph_path_operations.ipp
View file @
16b3fcfb
std::pair<bool, Path> Graph::directed_admissible_st_path(Node* s, Node* t, std::function<bool(Node* from, Edge* via)> guide){
std::
map<const
Node*, Edge*> predecessor;
std::
unordered_map<
Node*, Edge*> predecessor;
std::queue<Node*> active;
active.push(s);
...
...
@@ -20,7 +20,7 @@ std::pair<bool, Path> Graph::directed_admissible_st_path(Node* s, Node* t, std::
}
}
Path p = Path(this, predecessor,t);
Path p = Path(this, predecessor,
t);
if(predecessor.find(t) == predecessor.end() && s != t){
return {false, p};
}
...
...
@@ -35,3 +35,8 @@ std::pair<bool, Path> Graph::directed_admissible_st_path(Node* s, Node* t, std::
};
return this->directed_admissible_st_path(s, t, f);
}
std::pair<bool, const Path> Graph::directed_admissible_st_path(const Node* s, const Node* t, std::function<bool(const Node* from, const Edge* via)> guide) const {
std::cout << "calling path creation method for const graph" << std::endl;
return const_cast<Graph*>(this)->directed_admissible_st_path(const_cast<Node*>(s), const_cast<Node*>(t), [guide](Node* from, Edge* via){return guide(from, via);});
}
Graphtheory/Graph_select_operations.ipp
View file @
16b3fcfb
...
...
@@ -29,3 +29,34 @@ std::set<Node*> Graph::gather_nodes(std::vector<std::string> attributes){
return nodes;
}
std::set<const Edge*> Graph::gather_edges(std::vector<std::string> attributes) const {
std::set<const Edge*> edges;
for(Edge* e : this->_edges){
for(std::string attribute_name : attributes){
auto attribute_search = e->attribute(attribute_name);
if(attribute_search.first && attribute_search.second.value()){
edges.insert(e);
}
}
}
return edges;
}
std::set<const Node*> Graph::gather_nodes(std::vector<std::string> attributes) const {
std::set<const Node*> nodes;
for(Node* n : this->_nodes){
for(std::string attribute_name : attributes){
auto attribute_search = n->attribute(attribute_name);
if(attribute_search.first && attribute_search.second.value()){
nodes.insert(n);
}
}
}
return nodes;
}
Graphtheory/Graph_special_members_and_operators.ipp
View file @
16b3fcfb
...
...
@@ -11,17 +11,17 @@ Graph::Graph(Graph&& graph)
graph._template_edge_attributes = {};
}
std::pair< Graph, std::map<Node*, Node*> > Graph::copy_ret_lookup() const{
std::pair< Graph, std::map<
const
Node*, Node*> > Graph::copy_ret_lookup() const{
Graph copy (this->_template_edge_attributes, this->_template_node_attributes);
std::map<Node*, Node*> node_lookup;
std::map<
const
Node*, Node*> node_lookup;
for(Node* node : this->_nodes){
for(
const
Node* node : this->_nodes){
Node* new_node = copy.add_node(node);
node_lookup.insert({node, new_node});
}
for(Edge* edge : this->_edges){
for(
const
Edge* edge : this->_edges){
copy.add_edge(edge, node_lookup);
}
...
...
Graphtheory/Node.cpp
View file @
16b3fcfb
...
...
@@ -31,7 +31,7 @@ Node::Node(std::istream& is){
}
}
}
/*
bool Node::is_target() const {
for(Edge* e : this->incident()){
if(this == e->from()) return false;
...
...
@@ -45,14 +45,14 @@ bool Node::is_source() const {
}
return true;
}
*/
Node
::~
Node
(){
while
(
this
->
incident
().
begin
()
!=
this
->
incident
().
end
()){
delete
*
this
->
incident
().
begin
();
}
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Node
&
n
){
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Node
&
n
){
if
(
&
os
==
&
std
::
cout
){
os
<<
"
\033
[0;36m"
;
os
<<
"Node "
<<
n
.
description
()
<<
" ( "
;
...
...
Graphtheory/Node.h
View file @
16b3fcfb
...
...
@@ -85,17 +85,28 @@ public:
return
search
->
second
;
}
Attribute
&
add_attribute
(
const
std
::
string
attr_name
,
Attribute
attr
){
auto
[
iter
,
success
]
=
this
->
_attributes
.
insert
({
attr_name
,
attr
});
if
(
!
success
)
{
std
::
stringstream
text
;
text
<<
"
\"
"
<<
attr
<<
"
\"
is could not be added to Node "
<<
this
->
description
();
throw
std
::
range_error
(
text
.
str
());
}
return
iter
->
second
;
}
/*
bool is_target() const;
bool is_source() const;
*/
~
Node
();
// _debug_helpers
void
dump
();
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Node
&
n
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Node
&
n
);
std
::
istream
&
operator
>>
(
std
::
istream
&
is
,
Node
&
n
);
#endif
Graphtheory/Path.cpp
View file @
16b3fcfb
#include "Path.h"
#include <cfloat>
Path
::
Path
(
Graph
*
graph
,
std
::
unordered_map
<
Node
*
,
Edge
*>&
successor_matrix
,
Node
*
start
,
bool
invert_order
)
:
_owner
(
graph
){
std
::
unordered_map
<
Node
*
,
Edge
*>&
given_dir
=
this
->
_next_edge
;
std
::
unordered_map
<
Node
*
,
Edge
*>&
opposing_dir
=
this
->
_prev_edge
;
if
(
invert_order
){
given_dir
=
this
->
_prev_edge
;
opposing_dir
=
this
->
_next_edge
;
}
Path
::
Path
(
Graph
*
graph
,
std
::
map
<
const
Node
*
,
Edge
*>&
successor_matrix
,
Node
*
start
,
bool
invert_order
)
:
_owner
(
graph
){
Node
*
curr
=
start
;
auto
curr_iter
=
successor_matrix
.
find
(
curr
);
while
(
curr_iter
!=
successor_matrix
.
end
()){
given_dir
.
insert
({
curr
,
curr_iter
->
second
});
opposing_dir
.
insert
({
curr_iter
->
second
->
to
(
curr
),
curr_iter
->
second
});