Graph all locals are auto typed.

master
dmatetelki 10 years ago
parent 9787a9c013
commit 5160549dc9

@ -61,8 +61,11 @@ public:
Graph() : m_vertices() {} Graph() : m_vertices() {}
Graph(const Graph<V>& o) : m_vertices(o.m_vertices) {} Graph(const Graph<V>& o) : m_vertices(o.m_vertices) {}
Graph(Graph<V>&& o) : m_vertices(std::move(o.m_vertices)) {}
Graph(std::initializer_list<V> vertex_list); Graph(std::initializer_list<V> vertex_list);
Graph(const std::vector<V>& vertex_list);
Graph(std::initializer_list<Edge> edge_list); Graph(std::initializer_list<Edge> edge_list);
Graph(const std::vector<Edge>& edge_list);
Graph<V>& operator=(Graph<V> o) { swap(o); return *this; } Graph<V>& operator=(Graph<V> o) { swap(o); return *this; }
void swap(Graph& o) { std::swap(m_vertices, o.m_vertices); } void swap(Graph& o) { std::swap(m_vertices, o.m_vertices); }
@ -164,7 +167,15 @@ template <typename V>
inline Graph<V>::Graph(std::initializer_list<V> vertex_list) inline Graph<V>::Graph(std::initializer_list<V> vertex_list)
: Graph<V>() : Graph<V>()
{ {
for(const V& v : vertex_list) for(const auto& v : vertex_list)
addVertex(v);
}
template <typename V>
inline Graph<V>::Graph(const std::vector<V>& vertex_list)
: Graph<V>()
{
for(const auto& v : vertex_list)
addVertex(v); addVertex(v);
} }
@ -172,7 +183,15 @@ template <typename V>
inline Graph<V>::Graph(std::initializer_list<Edge> edge_list) inline Graph<V>::Graph(std::initializer_list<Edge> edge_list)
: Graph<V>() : Graph<V>()
{ {
for (const Edge& e : edge_list ) for (const auto& e : edge_list )
addEdge(e.source, e.destination);
}
template <typename V>
inline Graph<V>::Graph(const std::vector<Edge>& edge_list)
: Graph<V>()
{
for (const auto& e : edge_list )
addEdge(e.source, e.destination); addEdge(e.source, e.destination);
} }
@ -198,10 +217,10 @@ inline void Graph<V>::modifyVertex(const_reference old_data, const_reference new
if (old_data == new_data) if (old_data == new_data)
return; return;
std::vector<value_type> neighbours = neighboursOf(old_data); auto neighbours = neighboursOf(old_data);
for (auto &v : neighbours) { for (auto &v : neighbours) {
std::vector<value_type>& n_v = nonConstNeighboursOf(v); auto& n = nonConstNeighboursOf(v);
typename std::vector<value_type>::iterator n_it = std::find(n_v.begin(), n_v.end(), old_data); auto n_it = std::find(n.begin(), n.end(), old_data);
*n_it = new_data; *n_it = new_data;
} }
const auto number_of_removed_elements = m_vertices.erase(old_data); const auto number_of_removed_elements = m_vertices.erase(old_data);
@ -225,8 +244,8 @@ inline void Graph<V>::addEdge(const_reference source, const_reference destinatio
addVertex(source); addVertex(source);
addVertex(destination); addVertex(destination);
v_iterator source_it = m_vertices.find(source); auto source_it = m_vertices.find(source);
v_iterator destination_it = m_vertices.find(destination); auto destination_it = m_vertices.find(destination);
source_it->second.push_back(destination); source_it->second.push_back(destination);
destination_it->second.push_back(source); destination_it->second.push_back(source);
@ -236,7 +255,7 @@ template <typename V>
inline void Graph<V>::setEdges(const_reference source, const std::vector<value_type>& destinations) inline void Graph<V>::setEdges(const_reference source, const std::vector<value_type>& destinations)
{ {
addVertex(source); addVertex(source);
v_iterator source_it = m_vertices.find(source); auto source_it = m_vertices.find(source);
source_it->second.clear(); source_it->second.clear();
source_it->second = destinations; source_it->second = destinations;
@ -245,11 +264,11 @@ inline void Graph<V>::setEdges(const_reference source, const std::vector<value_t
template <typename V> template <typename V>
inline void Graph<V>::removeEdge(const_reference source, const_reference destination) inline void Graph<V>::removeEdge(const_reference source, const_reference destination)
{ {
v_iterator source_it = m_vertices.find(source); auto source_it = m_vertices.find(source);
if (source_it == m_vertices.end()) if (source_it == m_vertices.end())
return; return;
v_iterator destination_it = m_vertices.find(destination); auto destination_it = m_vertices.find(destination);
if (destination_it == m_vertices.end()) if (destination_it == m_vertices.end())
return; return;
@ -270,7 +289,7 @@ inline std::vector<typename Graph<V>::value_type> Graph<V>::vertices() const
template <typename V> template <typename V>
inline std::vector<V> Graph<V>::neighboursOf(const_reference data) const inline std::vector<V> Graph<V>::neighboursOf(const_reference data) const
{ {
v_const_iterator vertex_it = m_vertices.find(data); auto vertex_it = m_vertices.find(data);
if (vertex_it == m_vertices.end()) if (vertex_it == m_vertices.end())
return std::vector<V>(); return std::vector<V>();
else else
@ -280,7 +299,7 @@ inline std::vector<V> Graph<V>::neighboursOf(const_reference data) const
template <typename V> template <typename V>
inline std::vector<V>& Graph<V>::nonConstNeighboursOf(const_reference data) inline std::vector<V>& Graph<V>::nonConstNeighboursOf(const_reference data)
{ {
v_iterator vertex_it = m_vertices.find(data); auto vertex_it = m_vertices.find(data);
return vertex_it->second; return vertex_it->second;
} }

@ -2,10 +2,6 @@
#include "../catch.hpp" #include "../catch.hpp"
#include <algorithm>
#include <iostream>
#include <map>
TEST_CASE( "Graph creation", "[graph][data_structure]" ) { TEST_CASE( "Graph creation", "[graph][data_structure]" ) {
SECTION("Initial state") { SECTION("Initial state") {
@ -154,6 +150,15 @@ TEST_CASE( "Graph adding vertices", "[graph][data_structure]" ) {
REQUIRE( contains(g, 2) == true ); REQUIRE( contains(g, 2) == true );
} }
SECTION("Modify vertex to the same") {
Graph<int> g;
g.addVertex(1);
REQUIRE( contains(g, 1) == true );
g.modifyVertex(1, 1);
REQUIRE( contains(g, 1) == true );
}
SECTION("get array of vertices") { SECTION("get array of vertices") {
Graph<int> g; Graph<int> g;
g.addVertex(1); g.addVertex(1);
@ -215,6 +220,21 @@ TEST_CASE( "Graph adding edges", "[graph][data_structure]" ) {
REQUIRE( numberOfEdges(g) == 0 ); REQUIRE( numberOfEdges(g) == 0 );
} }
SECTION("Adding some edges, one edge mentioned from both directions") {
Graph<int> g = { {1, 2}, {2, 1} };
REQUIRE( numberOfVertices(g) == 2 );
REQUIRE( numberOfEdges(g) == 1*2 );
}
SECTION("Adding some edges, one edge mentioned from both directions v2") {
Graph<int> g = { {1, 2}, {1, 3}, {1, 4},
{2, 1}, {2, 3}, {2, 4},
{3, 1}, {3, 2}, {3, 4},
{4, 1}, {4, 2}, {4, 3} };
REQUIRE( numberOfVertices(g) == 4 );
REQUIRE( numberOfEdges(g) == 4*3 );
}
SECTION("Adding some edges then clear") { SECTION("Adding some edges then clear") {
Graph<int> g = { {1, 2}, {1, 3}, {3, 4} }; Graph<int> g = { {1, 2}, {1, 3}, {3, 4} };
g.clear(); g.clear();
@ -228,6 +248,20 @@ TEST_CASE( "Graph adding edges", "[graph][data_structure]" ) {
REQUIRE( numberOfEdges(g) == 3*2 ); REQUIRE( numberOfEdges(g) == 3*2 );
} }
SECTION("Removing edge with unexisting source") {
Graph<int> g = { {1, 2}, {1, 3}, {3, 4} };
REQUIRE( numberOfEdges(g) == 3*2 );
g.removeEdge(5, 4);
REQUIRE( numberOfEdges(g) == 3*2 );
}
SECTION("Removing edge with unexisting destination") {
Graph<int> g = { {1, 2}, {1, 3}, {3, 4} };
REQUIRE( numberOfEdges(g) == 3*2 );
g.removeEdge(1, 5);
REQUIRE( numberOfEdges(g) == 3*2 );
}
SECTION("connected vertices") { SECTION("connected vertices") {
Graph<int> g = { {1, 2}, {1, 3}, {3, 4} }; Graph<int> g = { {1, 2}, {1, 3}, {3, 4} };
REQUIRE( connected(g, 1, 2) == true ); REQUIRE( connected(g, 1, 2) == true );
@ -489,81 +523,3 @@ TEST_CASE( "Graph adding/removing with more data", "[graph][data_structure]" ) {
} }
} }
struct float2 {
float x, y;
inline float2() : x(0.0), y(0.0) {}
inline float2(float f1, float f2) : x(f1), y(f2) {}
};
inline bool operator ==(const float2& v1, const float2& v2) { return v1.x == v2.x && v1.y == v2.y; }
namespace std {
template <>
struct hash<float2>
{
std::size_t operator()(const float2& f2) const
{
std::size_t h1 = std::hash<float>()(f2.x);
std::size_t h2 = std::hash<float>()(f2.y);
return h1 ^ (h2 << 1);
}
};
}
int numberOfEdges(int N, int M) {
return (N-2)*(M-2)*8 // inside vertices have 8
+ 4*3 // corners have 3
+ (N-2)*2*5 + (M-2)*2*5; // sides has 5
}
// TEST_CASE( "Graph performance", "[graph][performance]" ) {
//
// SECTION("Adding 1000x1000 vertices") {
//
// const std::size_t N = 1000;
// const std::size_t M = 1000;
// Graph<float2> g;
// for (std::size_t i = 0; i < N; ++i)
// for (std::size_t j = 0; j < M; ++j)
// g.addVertex(float2(i, j));
//
// REQUIRE( numberOfVertices(g) == N*M );
// }
//
// SECTION("Adding 1000x1000 vertices and MANY edges") {
//
// /** Creating a big (N rows and M columns) grid.
// * Every vertex is connexted to it's 8 neighbours.
// *
// * +-+-+-+
// * |x+x+x|
// * +x+x+x+
// * |x+x+x|
// * +-+-+-+
// */
//
// const std::size_t N = 1000;
// const std::size_t M = 1000;
// Graph<float2> g;
//
// // inside
// for (std::size_t i = 1; i < N-1; ++i)
// for (std::size_t j = 1; j < M-1; ++j) {
// g.addEdge(float2(i, j), float2(i-1, j-1));
// g.addEdge(float2(i, j), float2(i-1, j));
// g.addEdge(float2(i, j), float2(i-1, j+1));
// g.addEdge(float2(i, j), float2(i, j-1));
// g.addEdge(float2(i, j), float2(i, j+1));
// g.addEdge(float2(i, j), float2(i+1, j-1));
// g.addEdge(float2(i, j), float2(i+1, j));
// g.addEdge(float2(i, j), float2(i+1, j+1));
// }
//
// REQUIRE( numberOfVertices(g) == N*M );
// // REQUIRE( numberOfEdges(g) == numberOfEdges(N, M)*2 );
// }
//
// }
Loading…
Cancel
Save