diff --git a/lib/graph/graph.hpp b/lib/graph/graph.hpp index cbc0abe..13c2776 100644 --- a/lib/graph/graph.hpp +++ b/lib/graph/graph.hpp @@ -1,5 +1,5 @@ -#ifndef GRAPH_H -#define GRAPH_H +#ifndef GRAPHWD_HPP +#define GRAPHWD_HPP #include #include @@ -7,10 +7,11 @@ #include +// weighed, directed template -class Graph { +class GraphWD { public: @@ -25,12 +26,12 @@ public: typedef E weight_type; typedef const E& const_weight_reference; - class vertex_iterator; - class edge_iterator; - private: struct EdgeTo; + + // @todo switch to std::unordered_map, std::vector>> for quicker neighbours & weights + // also turning the graph into unordered, weighted, with no multi & self edges by default typedef std::unordered_map > v_container; typedef typename v_container::iterator v_iterator; typedef typename v_container::const_iterator v_const_iterator; @@ -70,15 +71,14 @@ public: typedef Edge* edge_pointer; typedef Edge& edge_reference; -// public: - Graph(bool isdirected = true) : m_directed(isdirected), m_vertices() {} - Graph(const Graph& o) : m_directed(o.m_directed), m_vertices(o.m_vertices) {} - Graph(std::initializer_list vertex_list); - Graph(std::initializer_list edge_list); + GraphWD(bool isdirected = true) : m_directed(isdirected), m_vertices() {} + GraphWD(const GraphWD& o) : m_directed(o.m_directed), m_vertices(o.m_vertices) {} + GraphWD(std::initializer_list vertex_list); + GraphWD(std::initializer_list edge_list); - Graph& operator=(Graph o) { swap(o); return *this; } - void swap(Graph& o) { std::swap (m_directed, o.m_directed); std::swap(m_vertices, o.m_vertices); } + GraphWD& operator=(GraphWD o) { swap(o); return *this; } + void swap(GraphWD& o) { std::swap (m_directed, o.m_directed); std::swap(m_vertices, o.m_vertices); } // Properties bool directed() const { return m_directed; } @@ -108,14 +108,13 @@ public: // iterators - /// @todo make it random access class vertex_iterator : public std::iterator { - friend class Graph; + friend class GraphWD; public: typedef vertex_iterator self_type; @@ -144,17 +143,20 @@ public: v_const_iterator m_it; }; - vertex_iterator vertex_begin() { return vertex_iterator(m_vertices.begin()); } - const vertex_iterator vertex_begin() const { return vertex_iterator(m_vertices.begin()); } - vertex_iterator vertex_end() { return vertex_iterator(m_vertices.end()); } - const vertex_iterator vertex_end() const { return vertex_iterator(m_vertices.end()); } + typedef vertex_iterator iterator; + typedef const vertex_iterator const_iterator; + + iterator begin() { return iterator(m_vertices.begin()); } + const_iterator cbegin() const { return const_iterator(m_vertices.begin()); } + iterator end() { return iterator(m_vertices.end()); } + const_iterator cend() const { return const_iterator(m_vertices.end()); } private: static void eraseEdge(typename std::vector& v, const_reference data); static void eraseEdge(typename std::vector& v, const_reference data, const_weight_reference weight); - const bool m_directed; + bool m_directed; v_container m_vertices; }; @@ -162,21 +164,21 @@ private: // Edge template -inline Graph::Edge::Edge(const_reference s, const_reference d, const_weight_reference w) +inline GraphWD::Edge::Edge(const_reference s, const_reference d, const_weight_reference w) : source(s) , destination(d) , weight(w) {} template -inline Graph::Edge::Edge(const Edge& o) +inline GraphWD::Edge::Edge(const Edge& o) : source(o.source) , destination(o.destination) , weight(o.weight) {} template -inline void Graph::Edge::swap(Edge& o) +inline void GraphWD::Edge::swap(Edge& o) { std::swap(source, o.source); std::swap(destination, o.destination); @@ -186,45 +188,45 @@ inline void Graph::Edge::swap(Edge& o) // EdgeTo template -inline Graph::EdgeTo::EdgeTo(v_iterator destination, const_weight_reference weight) +inline GraphWD::EdgeTo::EdgeTo(v_iterator destination, const_weight_reference weight) : m_destination(destination) , m_weight(weight) {} template -inline void Graph::EdgeTo::swap(EdgeTo& o) +inline void GraphWD::EdgeTo::swap(EdgeTo& o) { std::swap(m_destination, o.m_destination); std::swap(m_weight, o.m_weight); } template -inline bool Graph::EdgeTo::operator==(const EdgeTo& other) const +inline bool GraphWD::EdgeTo::operator==(const EdgeTo& other) const { return m_destination == other.m_destination && m_weight == other.m_weight; } -// Graph +// GraphWD template -Graph::Graph(std::initializer_list vertex_list) - : Graph() +GraphWD::GraphWD(std::initializer_list vertex_list) + : GraphWD() { for(const V& v : vertex_list) addVertex(v); } template -Graph::Graph(std::initializer_list edge_list) - : Graph() +GraphWD::GraphWD(std::initializer_list edge_list) + : GraphWD() { for (const Edge& e : edge_list ) addEdge(e.source, e.destination, e.weight); } template -inline typename Graph::size_type Graph::numberOfEdges() const +inline typename GraphWD::size_type GraphWD::numberOfEdges() const { int sum = 0; for (const auto& v : m_vertices) @@ -234,17 +236,17 @@ inline typename Graph::size_type Graph::numberOfEdges() const } template -inline void Graph::addVertex(const_reference data) +inline void GraphWD::addVertex(const_reference data) { if (m_vertices.find(data) != m_vertices.end()) return; - std::pair::EdgeTo> > p(data, std::vector()); + std::pair::EdgeTo> > p(data, std::vector()); m_vertices.insert(p); } template -inline void Graph::removeVertex(const_reference data) +inline void GraphWD::removeVertex(const_reference data) { v_iterator it = m_vertices.find(data); if (it == m_vertices.end()) @@ -261,7 +263,7 @@ inline void Graph::removeVertex(const_reference data) } template -void Graph::addEdge(const_reference source, const_reference destination, const_weight_reference weight) +void GraphWD::addEdge(const_reference source, const_reference destination, const_weight_reference weight) { addVertex(source); addVertex(destination); @@ -269,13 +271,13 @@ void Graph::addEdge(const_reference source, const_reference destination, c v_iterator source_it = m_vertices.find(source); v_iterator destination_it = m_vertices.find(destination); - source_it->second.push_back(Graph::EdgeTo(destination_it, weight)); + source_it->second.push_back(GraphWD::EdgeTo(destination_it, weight)); if (!m_directed && source != destination) - destination_it->second.push_back(Graph::EdgeTo(source_it, weight)); + destination_it->second.push_back(GraphWD::EdgeTo(source_it, weight)); } template -inline void Graph::removeEdge(const_reference source, const_reference destination, const_weight_reference weight) +inline void GraphWD::removeEdge(const_reference source, const_reference destination, const_weight_reference weight) { v_iterator source_it = m_vertices.find(source); if (source_it == m_vertices.end()) @@ -291,7 +293,7 @@ inline void Graph::removeEdge(const_reference source, const_reference dest } template -inline void Graph::removeEdges(const_reference source, const_reference destination) +inline void GraphWD::removeEdges(const_reference source, const_reference destination) { v_iterator source_it = m_vertices.find(source); if (source_it == m_vertices.end()) @@ -307,7 +309,7 @@ inline void Graph::removeEdges(const_reference source, const_reference des } template -inline std::vector::value_type> Graph::vertices() const +inline std::vector::value_type> GraphWD::vertices() const { std::vector retval; for (const auto& v : m_vertices) @@ -317,7 +319,7 @@ inline std::vector::value_type> Graph::vertices() con } template -std::vector::value_type> Graph::neighboursOf(const_reference data) const +std::vector::value_type> GraphWD::neighboursOf(const_reference data) const { typename std::vector retval; v_const_iterator vertex_it = m_vertices.find(data); @@ -333,7 +335,7 @@ std::vector::value_type> Graph::neighboursOf(const_re } template -std::vector Graph::weights(const_reference source, const_reference destination) const +std::vector GraphWD::weights(const_reference source, const_reference destination) const { std::vector retval; v_const_iterator vertex_it = m_vertices.find(source); @@ -351,28 +353,28 @@ std::vector Graph::weights(const_reference source, const_reference dest } template -inline std::vector::Edge> Graph::edges() const +inline std::vector::Edge> GraphWD::edges() const { - std::vector::Edge> retval; + std::vector::Edge> retval; for (const auto& v : m_vertices) for (const auto& e : v.second) - retval.push_back(Graph::Edge(v.first, (e.m_destination)->first, e.m_weight)); + retval.push_back(GraphWD::Edge(v.first, (e.m_destination)->first, e.m_weight)); return retval; } template -void Graph::eraseEdge(typename std::vector& v, const_reference data) { +void GraphWD::eraseEdge(typename std::vector& v, const_reference data) { v.erase(std::remove_if(v.begin(), v.end(), [&data](const EdgeTo& e) { return e.m_destination->first == data; } ), v.end()); } template -void Graph::eraseEdge(typename std::vector& v, const_reference data, const_weight_reference weight ) { +void GraphWD::eraseEdge(typename std::vector& v, const_reference data, const_weight_reference weight ) { v.erase(std::remove_if(v.begin(), v.end(), [&data, &weight](const EdgeTo& e) { return e.m_destination->first == data && e.m_weight == weight; } ), v.end()); } -#endif // GRAPH_H +#endif // GRAPHWD_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 29095af..3e2abde 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,30 @@ +# set(CMAKE_CXX_FLAGS " -Wall -Wextra -pedantic -Weffc++ -Wshadow --std=c++0x -ggdb") +# set(CMAKE_CXX_COMPILER "/usr/lib/colorgcc/bin/g++") +# set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.8.2") + +# set(CMAKE_CXX_COMPILER "/home/denes/bin/colorgcc/g++") + +set (CXX_FLAGS "-Wall -Wextra -pedantic -Weffc++ -Wshadow " +# "-Wpointer-arith -Wcast-qual + "-std=c++11 " + "-ggdb -fprofile-arcs -ftest-coverage " + "-fopenmp -D_GLIBCXX_PARALLEL" + ) + +add_definitions( ${CXX_FLAGS} ) + +set (CMAKE_CXX_COMPILER "/usr/bin/g++-4.9.0") + find_package(CxxTest) + +# if ( NOT CXXTEST_FOUND ) +# message(FATAL_ERROR "Package CXXTEST required, but not found!") +# else() if(CXXTEST_FOUND) include_directories(${CXXTEST_INCLUDE_DIR} - ../lib) + ../lib + /usr/include/libxml2) enable_testing() @@ -10,8 +32,16 @@ if(CXXTEST_FOUND) generated_main.cpp graph/test_graph.hpp) + target_link_libraries(test_graph + gcov + gomp + xml2 + ) + endif() + add_custom_target( test - COMMAND ./test_graph + DEPENDS test_graph + COMMAND ./tools/run_test.sh ./test_graph ) \ No newline at end of file diff --git a/test/graph/test_graph.hpp b/test/graph/test_graph.hpp index de5c9fd..4df3b15 100644 --- a/test/graph/test_graph.hpp +++ b/test/graph/test_graph.hpp @@ -1,6 +1,24 @@ #include -#include "graph/graph.hpp" +#include + +// #include +// #include +// #include +// #include + +namespace std { + template <> + struct hash > + { + std::size_t operator()(const std::pair& k) const { + std::size_t h1 = std::hash()(k.first); + std::size_t h2 = std::hash()(k.second); + return h1 ^ (h2 << 1); + } + }; +} + namespace test { class TestSubsystem1DummyClassSuite; } @@ -10,149 +28,456 @@ class test::TestSubsystem1DummyClassSuite : public CxxTest::TestSuite public: - void testBasic() + void test_trivial() { + GraphWD g(false); + TS_ASSERT_EQUALS ( g.directed(), false ); + + GraphWD g1; + TS_ASSERT_EQUALS ( g1.directed(), true ); + + GraphWD g2; + TS_ASSERT_EQUALS ( g2.empty(), true ); + + GraphWD ,float> g3; + TS_ASSERT_EQUALS ( g3.numberOfVertices(), 0 ); + TS_ASSERT_EQUALS ( g3.numberOfEdges(), 0 ); + TS_ASSERT_EQUALS ( g3.contains(std::make_pair(2.4, 5.567)), false ); + TS_ASSERT_EQUALS ( g3.vertices().size(), 0 ); + TS_ASSERT_EQUALS ( g3.edges().size(), 0 ); + TS_ASSERT_EQUALS ( g3.empty(), true ); + } - Graph g; + void test_basic_vertices() + { + GraphWD g; - TS_ASSERT_EQUALS(g.empty(), true); - TS_ASSERT_EQUALS(g.numberOfVertices(), 0); - TS_ASSERT_EQUALS(g.numberOfEdges(), 0); + g.addVertex("a"); + g.addVertex("b"); + g.addVertex("c"); + TS_ASSERT_EQUALS ( g.vertices().size(), 3 ); + g.addVertex("d"); + g.addVertex("d"); + TS_ASSERT_EQUALS ( g.vertices().size(), 4 ); - int a = 2; - int b = 5; - TS_ASSERT_EQUALS(g.addEdge(a, b), false); + g.removeVertex("f"); + TS_ASSERT_EQUALS ( g.vertices().size(), 4 ); - TS_ASSERT_EQUALS(g.addVertex(a), true); - TS_ASSERT_EQUALS(g.addVertex(a), false); - TS_ASSERT_EQUALS(g.empty(), false); - TS_ASSERT_EQUALS(g.numberOfVertices(), 1); - { - const std::vector v = g.vertices(); - TS_ASSERT_EQUALS(v.size(), 1); - TS_ASSERT_EQUALS(*(v[0]), 2); - } + g.removeVertex("c"); + TS_ASSERT_EQUALS ( g.vertices().size(), 3 ); + g.removeVertex("c"); + TS_ASSERT_EQUALS ( g.vertices().size(), 3 ); + + for(const std::string& s : g.vertices()) + g.removeVertex(s); - TS_ASSERT_EQUALS(g.addEdge(a, b), false); + TS_ASSERT_EQUALS ( g.vertices().size(), 0 ); - TS_ASSERT_EQUALS(g.addVertex(b), true); - TS_ASSERT_EQUALS(g.numberOfVertices(), 2); + GraphWD g2 = { "a", "b", "c" }; + TS_ASSERT_EQUALS ( g2.vertices().size(), 3 ); + + } + + void test_basic_edges() { - const std::vector v = g.vertices(); - TS_ASSERT_EQUALS(v.size(), 2); - TS_ASSERT_EQUALS(*(v[0]), 2); - TS_ASSERT_EQUALS(*(v[1]), 5); + GraphWD g = { "a", "a", "b", "c", "d", "e" }; + g.addEdge("a", "a", 1); + g.addEdge("a", "b", 2); + g.addEdge("a", "c", 3); + + g.addEdge("c", "d", 4); + + TS_ASSERT_EQUALS ( g.edges().size(), 4 ); + TS_ASSERT_EQUALS ( g.neighboursOf("a").size(), 3 ); + TS_ASSERT_EQUALS ( g.neighboursOf("b").size(), 0 ); + TS_ASSERT_EQUALS ( g.neighboursOf("c").size(), 1 ); + TS_ASSERT_EQUALS ( g.neighboursOf("d").size(), 0 ); + TS_ASSERT_EQUALS ( g.neighboursOf("e").size(), 0 ); + + std::vector n = g.neighboursOf("a"); + TS_ASSERT_DIFFERS ( find(n.begin(), n.end(), "a"), n.end() ); + TS_ASSERT_DIFFERS ( find(n.begin(), n.end(), "b"), n.end() ); + TS_ASSERT_DIFFERS ( find(n.begin(), n.end(), "c"), n.end() ); + TS_ASSERT_EQUALS ( find(n.begin(), n.end(), "d"), n.end() ); + TS_ASSERT_EQUALS ( find(n.begin(), n.end(), "e"), n.end() ); + + std::vector w = g.weights("a", "b"); + TS_ASSERT_EQUALS ( w.size(), 1 ); + TS_ASSERT_EQUALS ( w[0], 2 ); + + // undirected + GraphWD g1(false); + g1.addVertex("a"); + g1.addVertex("b"); + g1.addVertex("c"); + g1.addVertex("d"); + g1.addVertex("e"); + + g1.addEdge("a", "a", 1); + g1.addEdge("a", "b", 2); + g1.addEdge("a", "c", 3); + g1.addEdge("c", "d", 4); + + TS_ASSERT_EQUALS ( g1.edges().size(), 4*2 - 1 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("a").size(), 3 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("b").size(), 1 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("c").size(), 2 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("d").size(), 1 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("e").size(), 0 ); } - TS_ASSERT_EQUALS(g.numberOfEdges(), 0); - TS_ASSERT_EQUALS(g.addEdge(a, b), true); + void test_list_ctor_from_vertices() + { + GraphWD g = { "a", "a", "b", "c", "d", "e" }; + + std::vector v = g.vertices(); - TS_ASSERT_EQUALS(g.numberOfEdges(), 1); + TS_ASSERT_EQUALS ( v.size(), 5 ); + } + + void test_move_ctor() { - const std::vector eb = g.weightsBetween(2, 5); - TS_ASSERT_EQUALS(eb.size(), 1); - TS_ASSERT_EQUALS(eb[0], 0); + + GraphWD g = { + {"a", "a", 1}, + {"a", "b", 2}, + {"a", "c", 3}, + {"c", "d", 4} }; + + GraphWD g1; + g1 = g; + + TS_ASSERT_EQUALS ( g.edges().size(), 4 ); + TS_ASSERT_EQUALS ( g.neighboursOf("a").size(), 3 ); + TS_ASSERT_EQUALS ( g.neighboursOf("b").size(), 0 ); + TS_ASSERT_EQUALS ( g.neighboursOf("c").size(), 1 ); + TS_ASSERT_EQUALS ( g.neighboursOf("d").size(), 0 ); + + TS_ASSERT_EQUALS ( g1.edges().size(), 4 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("a").size(), 3 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("b").size(), 0 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("c").size(), 1 ); + TS_ASSERT_EQUALS ( g1.neighboursOf("d").size(), 0 ); } - TS_ASSERT_EQUALS(g.weightsBetween(5, 2).size(), 0); - TS_ASSERT_EQUALS(g.neighboursOf(2).size(), 1); + + void test_list_ctor_from_edges() { - const std::vector n = g.neighboursOf(2); - TS_ASSERT_EQUALS(n.size(), 1); - TS_ASSERT_EQUALS(*(n[0]), 5); + + GraphWD g = { + {"a", "a", 1}, + {"a", "b", 2}, + {"a", "c", 3}, + {"c", "d", 4} }; + + TS_ASSERT_EQUALS ( g.vertices().size(), 4 ); + TS_ASSERT_EQUALS ( g.edges().size(), 4 ); + + TS_ASSERT_EQUALS ( g.neighboursOf("a").size(), 3 ); + TS_ASSERT_EQUALS ( g.neighboursOf("b").size(), 0 ); + TS_ASSERT_EQUALS ( g.neighboursOf("c").size(), 1 ); + TS_ASSERT_EQUALS ( g.neighboursOf("d").size(), 0 ); + TS_ASSERT_EQUALS ( g.neighboursOf("e").size(), 0 ); } - int c = 13; - int d = 1; - TS_ASSERT_EQUALS(g.numberOfVertices(), 2); - g.addVertex(c); - g.addVertex(d); - TS_ASSERT_EQUALS(g.numberOfVertices(), 4); - int vertices_array[] = {2, 5, 13, 1}; - std::vector v(vertices_array, vertices_array + sizeof(vertices_array) / sizeof(int) ); - Graph::vertex_iterator g_it2; - std::vector::iterator v_it = v.begin(); - g_it2 = g.vertex_begin(); - TS_ASSERT_EQUALS(g_it2, g.vertex_begin()); - - for (Graph::vertex_iterator g_it = g.vertex_begin(); - g_it != g.vertex_end(); - ++g_it, ++v_it) { - TS_ASSERT_EQUALS(*g_it, *v_it); + void test_adding_and_removing_vertices() + { + GraphWD g; + g.addVertex("a"); + g.addVertex("b"); + g.addVertex("c"); + g.addVertex("d"); + g.addVertex("e"); + g.addVertex("f"); + g.addVertex("g"); + + g.addEdge("a", "a", 1); + g.addEdge("a", "b", 2); + g.addEdge("a", "c", 3); + g.addEdge("c", "d", 4); + g.addEdge("c", "f", 5); + g.addEdge("f", "e", 6); + + TS_ASSERT_EQUALS ( g.vertices().size(), 7 ); + TS_ASSERT_EQUALS ( g.edges().size(), 6 ); + + g.removeVertex("c"); + + TS_ASSERT_EQUALS ( g.vertices().size(), 7-1 ); + TS_ASSERT_EQUALS ( g.edges().size(), 6-3 ); + + std::vector::Edge> es = g.edges(); +// TS_ASSERT_EQUALS ( es[0].source, "a" ); +// TS_ASSERT_EQUALS ( es[0].destination, "a" ); +// TS_ASSERT_EQUALS ( es[0].weight, 1 ); +// +// TS_ASSERT_EQUALS ( es[1].source, "a" ); +// TS_ASSERT_EQUALS ( es[1].destination, "b" ); +// TS_ASSERT_EQUALS ( es[1].weight, 2 ); +// +// TS_ASSERT_EQUALS ( es[2].source, "f" ); +// TS_ASSERT_EQUALS ( es[2].destination, "e" ); +// TS_ASSERT_EQUALS ( es[2].weight, 6 ); } + void test_removing_edges() + { - TS_ASSERT_EQUALS(g.neighboursOf(5).size(), 0); - - Graph g2; - g2.addVertex(1); - g2.addVertex(2); - g2.addVertex(3); - g2.addVertex(4); - - - TS_ASSERT_EQUALS(g2.addEdge(1, 2), true); - TS_ASSERT_EQUALS(g2.addEdge(1, 3), true); - TS_ASSERT_EQUALS(g2.addEdge(2, 4), true); - std::vector::Edge> e = g2.edges(); - TS_ASSERT_EQUALS(e.size(), 3); - - Graph::edge_iterator edge_it; - Graph::edge_iterator beee = g2.edge_begin(); - edge_it = beee; -// TS_ASSERT_EQUALS(edge_it, g2.edge_begin()); - int source = (*edge_it).getSource(); - int destination = (*edge_it).getDestination(); - TS_ASSERT_EQUALS (source, 1); - TS_ASSERT_EQUALS (destination, 2); - - ++edge_it; - source = (*edge_it).getSource(); - destination = (*edge_it).getDestination(); - TS_ASSERT_EQUALS (source, 1); - TS_ASSERT_EQUALS (destination, 3); - - ++edge_it; - source = (*edge_it).getSource(); - destination = (*edge_it).getDestination(); - TS_ASSERT_EQUALS (source, 2); - TS_ASSERT_EQUALS (destination, 4); - - int aasdads = 23; -// Graph::edge_iterator edge_it; - - for(/*Graph::edge_iterator*/ edge_it = g2.edge_begin(); edge_it != g2.edge_end(); ++edge_it) { - int source = (*edge_it).getSource(); - int destination = (*edge_it).getDestination(); -// std::cout << "edge: " -// << source << " " -// << destination << " " -// << (*edge_it).getWeight() << std::endl; + GraphWD g; + g.addVertex("a"); + g.addVertex("b"); + g.addVertex("c"); + g.addVertex("d"); + g.addVertex("e"); + g.addVertex("f"); + g.addVertex("g"); + + g.addEdge("a", "a", 1); + g.addEdge("a", "b", 21); // multiple to b + g.addEdge("a", "b", 22); + g.addEdge("a", "b", 23); + g.addEdge("a", "c", 3); + g.addEdge("c", "d", 4); + g.addEdge("c", "f", 5); + g.addEdge("f", "e", 6); + + g.removeEdge("c", "d", 4); + g.removeEdge("e", "f", 1234); + + g.removeEdges("a", "b"); + g.removeEdges("invalid", "b"); + + TS_ASSERT_EQUALS( g.vertices().size(), 7 ); + TS_ASSERT_EQUALS ( g.edges().size(), 4 ); + +// int j; GraphWD::edge_iterator e_it; +// for (j = 0, e_it = g.edge_begin(); +// e_it != g.edge_end(); +// ++e_it, ++j) +// switch (j) { +// case 0: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "a"); +// TS_ASSERT_EQUALS (e_it->weight, 1); +// break; +// case 1: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "c"); +// TS_ASSERT_EQUALS (e_it->weight, 3); +// break; +// case 2: TS_ASSERT_EQUALS (e_it->source, "c"); +// TS_ASSERT_EQUALS (e_it->destination, "f"); +// TS_ASSERT_EQUALS (e_it->weight, 5); +// break; +// case 3: TS_ASSERT_EQUALS (e_it->source, "f"); +// TS_ASSERT_EQUALS (e_it->destination, "e"); +// TS_ASSERT_EQUALS (e_it->weight, 6); +// break; +// } } - Graph::edge_iterator edge_it1 = g2.edge_begin(); - edge_it1 += 10; -// TS_ASSERT_EQUALS(edge_it1, g2.edge_end()); + void test_iterator() + { - Graph::edge_iterator edge_it2 = g2.edge_begin(); - edge_it2 += 2; - TS_ASSERT_EQUALS( (*edge_it2).getSource(), 2); - TS_ASSERT_EQUALS( (*edge_it2).getDestination(), 4); - TS_ASSERT_EQUALS((*edge_it2).getWeight(), 0); + GraphWD g; + g.addVertex("a"); + g.addVertex("b"); + g.addVertex("c"); + g.addVertex("d"); + g.addVertex("e"); + g.addVertex("f"); + g.addVertex("g"); + + g.addEdge("a", "a", 1); + g.addEdge("a", "b", 2); + g.addEdge("a", "c", 3); + g.addEdge("c", "d", 4); + g.addEdge("c", "f", 5); + g.addEdge("f", "e", 6); + +// int i; GraphWD::vertex_iterator v_it; +// for (i = 0, v_it = g.begin(); +// v_it != g.end(); +// ++v_it, ++i) +// switch (i) { +// case 0: TS_ASSERT_EQUALS (*v_it, "a"); break; +// case 1: TS_ASSERT_EQUALS (*v_it, "b"); break; +// case 2: TS_ASSERT_EQUALS (*v_it, "c"); break; +// case 3: TS_ASSERT_EQUALS (*v_it, "d"); break; +// case 4: TS_ASSERT_EQUALS (*v_it, "e"); break; +// case 5: TS_ASSERT_EQUALS (*v_it, "f"); break; +// case 6: TS_ASSERT_EQUALS (*v_it, "g"); break; +// } + +// int j; GraphWD::edge_iterator e_it; +// for (j = 0, e_it = g.edge_begin(); +// e_it != g.edge_end(); +// ++e_it, ++j) +// switch (j) { +// case 0: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "a"); +// TS_ASSERT_EQUALS (e_it->weight, 1); +// break; +// case 1: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "b"); +// TS_ASSERT_EQUALS (e_it->weight, 2); +// break; +// case 2: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "c"); +// TS_ASSERT_EQUALS (e_it->weight, 3); +// break; +// case 3: TS_ASSERT_EQUALS (e_it->source, "c"); +// TS_ASSERT_EQUALS (e_it->destination, "d"); +// TS_ASSERT_EQUALS (e_it->weight, 4); +// break; +// case 4: TS_ASSERT_EQUALS (e_it->source, "c"); +// TS_ASSERT_EQUALS (e_it->destination, "f"); +// TS_ASSERT_EQUALS (e_it->weight, 5); +// break; +// case 5: TS_ASSERT_EQUALS (e_it->source, "f"); +// TS_ASSERT_EQUALS (e_it->destination, "e"); +// TS_ASSERT_EQUALS (e_it->weight, 6); +// break; +// } + +// g.removeVertex("c"); +// +// for (i = 0, v_it = g.vertex_begin(); +// v_it != g.vertex_end(); +// ++v_it, ++i) +// switch (i) { +// case 0: TS_ASSERT_EQUALS (*v_it, "a"); break; +// case 1: TS_ASSERT_EQUALS (*v_it, "b"); break; +// case 2: TS_ASSERT_EQUALS (*v_it, "d"); break; +// case 3: TS_ASSERT_EQUALS (*v_it, "e"); break; +// case 4: TS_ASSERT_EQUALS (*v_it, "f"); break; +// case 5: TS_ASSERT_EQUALS (*v_it, "g"); break; +// } +// +// for (j = 0, e_it = g.edge_begin(); +// e_it != g.edge_end(); +// ++e_it, ++j) +// switch (j) { +// case 0: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "a"); +// TS_ASSERT_EQUALS (e_it->weight, 1); +// break; +// case 1: TS_ASSERT_EQUALS (e_it->source, "a"); +// TS_ASSERT_EQUALS (e_it->destination, "b"); +// TS_ASSERT_EQUALS (e_it->weight, 2); +// break; +// case 2: TS_ASSERT_EQUALS (e_it->source, "f"); +// TS_ASSERT_EQUALS (e_it->destination, "e"); +// TS_ASSERT_EQUALS (e_it->weight, 6); +// break; +// } + } -// toDot(g2, "itt.dot"); -// Graph read_g; -// fromDot("itt.dot", read_g); -// TS_ASSERT_EQUALS(g2, read_g); + void test_wights() + { + GraphWD g; + g.addVertex("a"); + g.addVertex("b"); + g.addVertex("c"); + g.addVertex("d"); + g.addVertex("e"); + g.addVertex("f"); + g.addVertex("g"); + + g.addEdge("a", "a", 1); + g.addEdge("a", "b", 2); + g.addEdge("a", "c", 3); + g.addEdge("c", "d", 4); + g.addEdge("c", "f", 5); + g.addEdge("f", "e", 6); + + TS_ASSERT_EQUALS ( g.weights("a", "a").size(), 1 ); + TS_ASSERT_EQUALS ( g.weights("a", "b").size(), 1 ); + TS_ASSERT_EQUALS ( g.weights("a", "c").size(), 1 ); + TS_ASSERT_EQUALS ( g.weights("c", "d").size(), 1 ); + TS_ASSERT_EQUALS ( g.weights("f", "e").size(), 1 ); + + TS_ASSERT_EQUALS ( g.weights("a", "d").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("a", "f").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("a", "e").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("a", "d").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("d", "e").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("b", "f").size(), 0 ); + + // directed + TS_ASSERT_EQUALS ( g.weights("a", "a").size(), 1 ); + TS_ASSERT_EQUALS ( g.weights("b", "b").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("c", "a").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("d", "c").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("f", "c").size(), 0 ); + TS_ASSERT_EQUALS ( g.weights("e", "f").size(), 0 ); + } +// /// @todo put algorithm tests to another suite +// void test_dijkstra() +// { +// +// // from http://en.wikipedia.org/wiki/File:Dijkstra_Animation.gif +// GraphWDWD d(false); +// d.addVertex(1); +// d.addVertex(2); +// d.addVertex(3); +// d.addVertex(4); +// d.addVertex(5); +// d.addVertex(6); +// +// d.addVertex(7); // unconnected extra +// d.addVertex(8); +// d.addVertex(9); +// +// d.addEdge(1, 2, 7); +// d.addEdge(1, 3, 9); +// d.addEdge(1, 6, 14); +// d.addEdge(2, 3, 10); +// d.addEdge(2, 4, 15); +// d.addEdge(3, 4, 11); +// d.addEdge(3, 6, 2); +// d.addEdge(4, 5, 6); +// d.addEdge(5, 6, 9); +// +// d.addEdge(8, 9, 9); +// +// std::pair, std::unordered_map< int, int> > shortest_path = dijkstra_shortest_path_v2(d, 1); +// +// TS_ASSERT_EQUALS ( shortest_path.first[1], 0 ); +// TS_ASSERT_EQUALS ( shortest_path.first[2], 7 ); +// TS_ASSERT_EQUALS ( shortest_path.first[3], 9 ); +// TS_ASSERT_EQUALS ( shortest_path.first[4], 20 ); +// TS_ASSERT_EQUALS ( shortest_path.first[5], 20 ); +// TS_ASSERT_EQUALS ( shortest_path.first[6], 11 ); +// TS_ASSERT_EQUALS ( shortest_path.first.size(), 6 ); +// +// TS_ASSERT_EQUALS ( shortest_path.second[2], 1 ); +// TS_ASSERT_EQUALS ( shortest_path.second[3], 1 ); +// TS_ASSERT_EQUALS ( shortest_path.second[4], 3 ); +// TS_ASSERT_EQUALS ( shortest_path.second[5], 6 ); +// TS_ASSERT_EQUALS ( shortest_path.second[6], 3 ); +// TS_ASSERT_EQUALS ( shortest_path.second.size(), 5 ); +// } +// +// /// @todo put XML tests to another suite +// void test_read_from_XML() +// { +// +// GraphWD< std::pair > g_xml = readGraphWD("/home/denes/projects/graph/lib/graph/graph_example.xml"); +// // for (std::pair v : g_xml.vertices()) +// // std::cout << TToStr(v) << std::endl; +// // +// // for (GraphWD< std::pair >::Edge e : g_xml.edges()) +// // std::cout << TToStr(e.source) << " -> " << TToStr(e.destination) << std::endl; +// } + +// { + // std::vector< std::pair > points = { +// {1, 1}, +// }; + +// GraphWD< std::pair > g_d = delaunay_triangulation(points); +// } - Graph g4; - g4.addVertex(3); - Graph g5 = g4; - Graph g6; - g6 = g5; - g6.removeVertex(3); -} };