Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stian Jakobsen
DTE-3603 Template Source Base
Commits
cd3cb4cd
Commit
cd3cb4cd
authored
Oct 06, 2021
by
Stian Jakobsen
Browse files
Merge branch 'week2' into 'master'
Merge Week2 See merge request sja044/dte-3603_template_source_base!9
parents
a5e59c6c
c3b5808e
Changes
28
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
cd3cb4cd
...
...
@@ -56,11 +56,11 @@ target_compile_definitions(Boost::graph
add_subdirectory
(
predef_shared
)
# Include internal library subfolders
add_subdirectory
(
week2
)
add_subdirectory
(
day1_2_sort
)
add_subdirectory
(
day3_string_match
)
add_subdirectory
(
day4_graph_traversal
)
add_subdirectory
(
day5_graph_path_finding
)
add_subdirectory
(
week2_zombie
)
###########################################
# Qt creator dummy target
...
...
flow_graphs/empty_graph.txt
0 → 100644
View file @
cd3cb4cd
1
1
S T
\ No newline at end of file
flow_graphs/initial_example_graph.txt
0 → 100644
View file @
cd3cb4cd
2
3 3
S 1,2 2 2
S 1,3 1 2
1,3 1,2 2 1
1,2 2,1 2 1
1,3 2,2 3 3
2,1 T 2 2
2,2 T 2 2
\ No newline at end of file
flow_graphs/mit_graph_example.txt
0 → 100644
View file @
cd3cb4cd
2
1 1
S U 3 1
S X 2 1
X U 3 1
X Y 3 1
U V 2 1
V X 1 1
V T 3 1
Y T 2 1
\ No newline at end of file
predef_shared/include/predef_shared/concepts/graphs.h
View file @
cd3cb4cd
...
...
@@ -54,9 +54,9 @@ namespace dte3603::predef::concepts::graph
};
template
<
typename
Graph_T
>
concept
BidirectionalGraph
=
Graph
<
Graph_T
>
and
std
::
same_as
<
typename
Graph_T
::
directed_selector
,
boost
::
bidirectionalS
>
;
concept
BidirectionalGraph
=
Graph
<
Graph_T
>
and
std
::
same_as
<
typename
Graph_T
::
directed_selector
,
boost
::
bidirectionalS
>
;
}
// namespace dte3603::predef::concepts::graph
...
...
predef_shared/include/predef_shared/testing_gold/max_flow_testing_fixtures.h
View file @
cd3cb4cd
#ifndef DTE3603_PREDEF_TESTING_WEEK2_MAX_FLOW_FIXTURES_H
#define DTE3603_PREDEF_TESTING_WEEK2_MAX_FLOW_FIXTURES_H
#include
"max_flow_testing_gold.h"
// gtest
#include
<gtest/gtest.h>
// Inspired/based on the supplied week 1 testing fixtures and adapted for flow
// algorithms
namespace
dte3603
::
predef
::
testing
::
week2_zombie
::
fixtures
{
template
<
typename
GoldGraph_T
>
struct
GoldGraphTestF
:
::
testing
::
Test
{
using
GoldGraph
=
GoldGraph_T
;
using
::
testing
::
Test
::
Test
;
~
GoldGraphTestF
()
override
{}
std
::
unique_ptr
<
GoldGraph
>
gold
;
void
SetUp
()
final
{
gold
=
std
::
make_unique
<
GoldGraph
>
();
}
void
TearDown
()
final
{
gold
.
release
();
}
};
using
EmptyGraphF
=
GoldGraphTestF
<
gold
::
EmptyGraph
>
;
using
FirstExampleGraphF
=
GoldGraphTestF
<
gold
::
FirstExampleGraph
>
;
using
MiTExampleGraphF
=
GoldGraphTestF
<
gold
::
MiTGraphExample
>
;
// // Special purpose fixtures
// using SingleNodeDAGF = GoldGraphTestF<gold::SingleNodeDAG>;
// using TreeDAGF = GoldGraphTestF<gold::TreeDAG>;
// // Brute force test fixtures
// using DAGOneF = GoldGraphTestF<gold::DAGOne>;
// using DAGTwoF = GoldGraphTestF<gold::DAGTwo>;
// using DAGThreeF = GoldGraphTestF<gold::DAGThree>;
}
// namespace dte3603::predef::testing::week2_zombie::fixtures
#endif // DTE3603_PREDEF_TESTING_WEEK2_MAX_FLOW_FIXTURES_H
predef_shared/include/predef_shared/testing_gold/max_flow_testing_gold.h
0 → 100644
View file @
cd3cb4cd
#ifndef DTE3603_PREDEF_TESTING_WEEK2_MAX_FLOW_GOLD_H
#define DTE3603_PREDEF_TESTING_WEEK2_MAX_FLOW_GOLD_H
// boost
#include
<boost/graph/adjacency_list.hpp>
// gtest
#include
<gtest/gtest.h>
// stl
#include
<concepts>
#include
<cstdlib>
#include
<vector>
#include
<algorithm>
#include
<random>
#include
<filesystem>
#include
<iostream>
#include
<fstream>
// Inspired/based on the supplied week 1 testing gold and adapted for flow
// algorithms
namespace
dte3603
::
predef
::
testing
::
week2_zombie
{
namespace
detail
{
namespace
types
{
namespace
properties
{
struct
NodeProperties
{
std
::
string
name
;
};
struct
EdgeProperties
{
double
flow
;
double
cost
;
double
flow_capacity
;
};
using
GraphProperties
=
boost
::
no_property
;
}
// namespace properties
using
BidirectionalGraph
=
boost
::
adjacency_list
<
boost
::
vecS
,
boost
::
vecS
,
boost
::
bidirectionalS
,
properties
::
NodeProperties
,
properties
::
EdgeProperties
,
properties
::
GraphProperties
>
;
}
// namespace types
template
<
typename
GraphType_T
>
struct
GoldGraphTemplate
{
using
Graph
=
GraphType_T
;
using
VP
=
typename
Graph
::
vertex_property_type
;
using
EP
=
typename
Graph
::
edge_property_type
;
using
VD
=
typename
Graph
::
vertex_descriptor
;
using
ED
=
typename
Graph
::
edge_descriptor
;
using
VDVector
=
std
::
vector
<
VD
>
;
using
VDVecVector
=
std
::
vector
<
VDVector
>
;
GoldGraphTemplate
()
=
default
;
virtual
~
GoldGraphTemplate
()
=
default
;
Graph
&
graph
()
{
return
m_graph
;
}
Graph
m_graph
;
};
}
// namespace detail
namespace
gold
{
class
EmptyGraph
:
public
detail
::
GoldGraphTemplate
<
detail
::
types
::
BidirectionalGraph
>
{
// Getting our current path and gonig for the flow_graphs folder that will
// hopefully be present *may* require platform-specific code for paths,
// since Windows can be funky.
std
::
string
graph_src_path
=
std
::
filesystem
::
current_path
().
append
(
"flow_graphs/empty_graph.txt"
);
// Using ifstream rather than fstream since we only need to read the file
std
::
ifstream
input_reader
;
// number of floors and nodes as read from the file "header"
int
n_floors
;
std
::
vector
<
int
>
n_nodes
;
// Vertex descriptors for the source and sink to be read from file
VD
source
,
sink
;
public:
EmptyGraph
()
{
input_reader
.
open
(
graph_src_path
);
input_reader
>>
n_floors
;
int
v
;
// May need to implement some safety checks at some point
for
(
auto
i
=
0
;
i
<
n_floors
;
i
++
)
{
input_reader
>>
v
;
n_nodes
.
push_back
(
v
);
}
// Better while that had to be exchanged for peek with eof to allow for
// string node names
// TODO: Replace with better alternative
// double x;
// while (input_reader >> x) {
// int cost, capacity, n1, n2;
// input_reader >> node_one >> node_two >> cost >> capacity;
// }
// While that runs as long as the next line isn't end of line (-1), not
// ideal
while
(
input_reader
.
peek
()
!=
EOF
)
{
std
::
string
v1
,
v2
;
double
cost
,
flow_cap
;
input_reader
>>
v1
>>
v2
>>
flow_cap
>>
cost
;
source
=
boost
::
add_vertex
(
VP
{.
name
=
v1
},
m_graph
);
sink
=
boost
::
add_vertex
(
VP
{.
name
=
v2
},
m_graph
);
boost
::
add_edge
(
source
,
sink
,
EP
{.
flow
=
0.
,
.
cost
=
cost
,
.
flow_capacity
=
flow_cap
},
m_graph
);
}
}
~
EmptyGraph
()
override
{}
VD
&
Source
()
{
return
source
;
}
VD
&
Sink
()
{
return
sink
;
}
// Empty graph so max flow is 0, and there is no shortest path (since
// there is no path)
auto
maxFlowGold
()
const
{
return
0.
;
}
};
// Initial graph example given by professor in task description
class
FirstExampleGraph
:
public
detail
::
GoldGraphTemplate
<
detail
::
types
::
BidirectionalGraph
>
{
// Getting our current path and gonig for the flow_graphs folder that will
// hopefully be present *may* require platform-specific code for paths,
// since Windows can be funky.
std
::
string
graph_src_path
=
std
::
filesystem
::
current_path
().
append
(
"flow_graphs/initial_example_graph.txt"
);
// Using ifstream rather than fstream since we only need to read the file
std
::
ifstream
input_reader
;
// number of floors and nodes as read from the file "header"
int
n_floors
;
std
::
vector
<
int
>
n_nodes
;
// map of vertices in graph as read from file
std
::
unordered_map
<
std
::
string
,
VD
>
v_map
;
// Vertex descriptors for the source and sink to be read from file
VD
source
,
sink
;
public:
FirstExampleGraph
()
{
input_reader
.
open
(
graph_src_path
);
input_reader
>>
n_floors
;
// May need to implement some safety checks at some point
int
v
;
for
(
auto
i
=
0
;
i
<
n_floors
;
i
++
)
{
input_reader
>>
v
;
}
// Finding and adding all edges from file
while
(
input_reader
.
peek
()
!=
EOF
)
{
std
::
string
v1
,
v2
;
double
cost
,
flow_cap
;
input_reader
>>
v1
>>
v2
>>
flow_cap
>>
cost
;
insertInMap
(
v1
,
"S"
,
source
);
insertInMap
(
v2
,
"T"
,
sink
);
boost
::
add_edge
(
v_map
.
at
(
v1
),
v_map
.
at
(
v2
),
EP
{.
flow
=
0.
,
.
cost
=
cost
,
.
flow_capacity
=
flow_cap
},
m_graph
);
}
}
// Would ideally be a universal helper method for all test classes.
// Could not work around an issue to solve this, ideally done in the
// future.
void
insertInMap
(
std
::
string
&
v
,
std
::
string
target
,
VD
&
v_target
)
{
if
(
!
v_map
.
contains
(
v
))
{
if
(
v
==
target
)
{
v_target
=
boost
::
add_vertex
(
VP
{.
name
=
v
},
m_graph
);
v_map
.
insert
(
std
::
make_pair
(
v
,
v_target
));
}
else
{
v_map
.
insert
(
std
::
make_pair
(
v
,
boost
::
add_vertex
(
VP
{.
name
=
v
},
m_graph
)));
}
}
}
~
FirstExampleGraph
()
override
{}
VD
&
Source
()
{
return
source
;
}
VD
&
Sink
()
{
return
sink
;
}
auto
maxFlowGold
()
const
{
return
3.
;
}
};
// MiT Graph example from MiT lecture
class
MiTGraphExample
:
public
detail
::
GoldGraphTemplate
<
detail
::
types
::
BidirectionalGraph
>
{
// Getting our current path and gonig for the flow_graphs folder that will
// hopefully be present *may* require platform-specific code for paths,
// since Windows can be funky.
std
::
string
graph_src_path
=
std
::
filesystem
::
current_path
().
append
(
"flow_graphs/mit_graph_example.txt"
);
// Using ifstream rather than fstream since we only need to read the file
std
::
ifstream
input_reader
;
// number of floors and nodes as read from the file "header"
std
::
vector
<
int
>
n_nodes
;
int
n_floors
;
// map of vertices in graph as read from file
std
::
unordered_map
<
std
::
string
,
VD
>
v_map
;
// Vertex descriptors for the source and sink to be read from file
VD
source
,
sink
;
public:
MiTGraphExample
()
{
input_reader
.
open
(
graph_src_path
);
input_reader
>>
n_floors
;
int
v
;
for
(
auto
i
=
0
;
i
<
n_floors
;
i
++
)
{
input_reader
>>
v
;
}
while
(
input_reader
.
peek
()
!=
EOF
)
{
std
::
string
v1
,
v2
;
double
cost
,
flow_cap
;
input_reader
>>
v1
>>
v2
>>
flow_cap
>>
cost
;
insertInMap
(
v1
,
"S"
,
source
);
insertInMap
(
v2
,
"T"
,
sink
);
boost
::
add_edge
(
v_map
.
at
(
v1
),
v_map
.
at
(
v2
),
EP
{.
flow
=
0.
,
.
cost
=
cost
,
.
flow_capacity
=
flow_cap
},
m_graph
);
}
}
// Would ideally be a universal helper method for all test classes.
// Could not work around an issue to solve this in the time remaining,
// ideally done in the future.
void
insertInMap
(
std
::
string
&
v
,
std
::
string
target
,
VD
&
v_target
)
{
if
(
!
v_map
.
contains
(
v
))
{
if
(
v
==
target
)
{
v_target
=
boost
::
add_vertex
(
VP
{.
name
=
v
},
m_graph
);
v_map
.
insert
(
std
::
make_pair
(
v
,
v_target
));
}
else
{
v_map
.
insert
(
std
::
make_pair
(
v
,
boost
::
add_vertex
(
VP
{.
name
=
v
},
m_graph
)));
}
}
}
~
MiTGraphExample
()
override
{}
VD
&
Source
()
{
return
source
;
}
VD
&
Sink
()
{
return
sink
;
}
auto
maxFlowGold
()
const
{
return
4.
;
}
};
}
// namespace gold
}
// namespace dte3603::predef::testing::week2_zombie
#endif // DTE3603_PREDEF_TESTING_GRAPH_GOLD_H
predef_shared/include/predef_shared/testing_gold/min_cost_flow_testing_fixtures.h
View file @
cd3cb4cd
#ifndef DTE3603_PREDEF_TESTING_WEEK2_MIN_COST_FLOW_FIXTURES_H
#define DTE3603_PREDEF_TESTING_WEEK2_MIN_COST_FLOW_FIXTURES_H
#include
"min_cost_flow_testing_gold.h"
// gtest
#include
<gtest/gtest.h>
// Inspired/based on the supplied week 1 testing fixtures and adapted for flow
// algorithms
namespace
dte3603
::
predef
::
testing
::
week2_zombie
::
fixtures
{
template
<
typename
GoldGraph_T
>
struct
GoldGraphTestF
:
::
testing
::
Test
{
using
GoldGraph
=
GoldGraph_T
;
using
::
testing
::
Test
::
Test
;
~
GoldGraphTestF
()
override
{}
std
::
unique_ptr
<
GoldGraph
>
gold
;
void
SetUp
()
final
{
gold
=
std
::
make_unique
<
GoldGraph
>
();
}
void
TearDown
()
final
{
gold
.
release
();
}
};
using
EmptyGraphF
=
GoldGraphTestF
<
gold
::
EmptyGraph
>
;
using
FirstExampleGraphF
=
GoldGraphTestF
<
gold
::
FirstExampleGraph
>
;
using
MiTExampleGraphF
=
GoldGraphTestF
<
gold
::
MiTGraphExample
>
;
// // Special purpose fixtures
// using SingleNodeDAGF = GoldGraphTestF<gold::SingleNodeDAG>;
// using TreeDAGF = GoldGraphTestF<gold::TreeDAG>;
// // Brute force test fixtures
// using DAGOneF = GoldGraphTestF<gold::DAGOne>;
// using DAGTwoF = GoldGraphTestF<gold::DAGTwo>;
// using DAGThreeF = GoldGraphTestF<gold::DAGThree>;
}
// namespace dte3603::predef::testing::week2_zombie::fixtures
#endif // DTE3603_PREDEF_TESTING_WEEK2_MIN_COST_FLOW_FIXTURES_H
predef_shared/include/predef_shared/testing_gold/min_cost_flow_testing_gold.h
0 → 100644
View file @
cd3cb4cd
#ifndef DTE3603_PREDEF_TESTING_WEEK2_MIN_COST_FLOW_GOLD_H
#define DTE3603_PREDEF_TESTING_WEEK2_MIN_COST_FLOW_GOLD_H
// boost
#include
<boost/graph/adjacency_list.hpp>
// gtest
#include
<gtest/gtest.h>
// stl
#include
<concepts>
#include
<cstdlib>
#include
<vector>
#include
<algorithm>
#include
<random>
#include
<filesystem>
#include
<iostream>
#include
<fstream>
// Inspired/based on the supplied week 1 testing gold and adapted for flow
// algorithms
namespace
dte3603
::
predef
::
testing
::
week2_zombie
{
namespace
detail
{
namespace
types
{
namespace
properties
{
struct
NodeProperties
{
std
::
string
name
;
};
struct
EdgeProperties
{
double
flow
;
double
cost
;
double
flow_capacity
;
};
using
GraphProperties
=
boost
::
no_property
;
}
// namespace properties
using
BidirectionalGraph
=
boost
::
adjacency_list
<
boost
::
vecS
,
boost
::
vecS
,
boost
::
bidirectionalS
,
properties
::
NodeProperties
,
properties
::
EdgeProperties
,
properties
::
GraphProperties
>
;
}
// namespace types
template
<
typename
GraphType_T
>
struct
GoldGraphTemplate
{
using
Graph
=
GraphType_T
;
using
VP
=
typename
Graph
::
vertex_property_type
;
using
EP
=
typename
Graph
::
edge_property_type
;
using
VD
=
typename
Graph
::
vertex_descriptor
;
using
ED
=
typename
Graph
::
edge_descriptor
;
using
VDVector
=
std
::
vector
<
VD
>
;
using
VDVecVector
=
std
::
vector
<
VDVector
>
;
GoldGraphTemplate
()
=
default
;
virtual
~
GoldGraphTemplate
()
=
default
;
Graph
&
graph
()
{
return
m_graph
;
}
Graph
m_graph
;
};
}
// namespace detail
namespace
gold
{
class
EmptyGraph
:
public
detail
::
GoldGraphTemplate
<
detail
::
types
::
BidirectionalGraph
>
{
// Getting our current path and gonig for the flow_graphs folder that will
// hopefully be present *may* require platform-specific code for paths,
// since Windows can be funky.
std
::
string
graph_src_path
=
std
::
filesystem
::
current_path
().
append
(
"flow_graphs/empty_graph.txt"
);
// Using ifstream rather than fstream since we only need to read the file
std
::
ifstream
input_reader
;
// number of floors and nodes as read from the file "header"
int
n_floors
;
std
::
vector
<
int
>
n_nodes
;
// Vertex descriptors for the source and sink to be read from file
VD
source
,
sink
;
public:
EmptyGraph
()
{
input_reader
.
open
(
graph_src_path
);
input_reader
>>
n_floors
;
int
v
;
// May need to implement some safety checks at some point
for
(
auto
i
=
0
;
i
<
n_floors
;
i
++
)
{
input_reader
>>
v
;
n_nodes
.
push_back
(
v
);
}
// Better while that had to be exchanged for peek with eof to allow for
// string node names
// TODO: Replace with better alternative
// double x;
// while (input_reader >> x) {
// int cost, capacity, n1, n2;
// input_reader >> node_one >> node_two >> cost >> capacity;
// }
// While that runs as long as the next line isn't end of line (-1), not
// ideal
while
(
input_reader
.
peek
()
!=
EOF
)
{
std
::
string
v1
,
v2
;
double
cost
,
flow_cap
;
input_reader
>>
v1
>>
v2
>>
flow_cap
>>
cost
;
source
=
boost
::
add_vertex
(
VP
{.
name
=
v1
},
m_graph
);
sink
=
boost
::
add_vertex
(
VP
{.
name
=
v2
},
m_graph
);
boost
::
add_edge
(
source
,
sink
,
EP
{.
flow
=
0.
,
.
cost
=
cost
,
.
flow_capacity
=
flow_cap
},
m_graph
);
}
}
~
EmptyGraph
()
override
{}
VD
&
Source
()
{
return
source
;
}
VD
&
Sink
()
{
return
sink
;
}
VDVecVector
bellmanFordGold
()
const
{
return
{};
}
};
// Initial graph example given by professor in task description
class
FirstExampleGraph
:
public
detail
::
GoldGraphTemplate
<
detail
::
types
::
BidirectionalGraph
>
{
// Getting our current path and gonig for the flow_graphs folder that will
// hopefully be present *may* require platform-specific code for paths,
// since Windows can be funky.
std
::
string
graph_src_path
=
std
::
filesystem
::
current_path
().
append
(