|
|
@ -29,6 +29,18 @@ public:
|
|
|
|
class vertex_iterator;
|
|
|
|
class vertex_iterator;
|
|
|
|
class edge_iterator;
|
|
|
|
class edge_iterator;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VertexAlreadyExistsExcepttion : public std::logic_error
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
VertexAlreadyExistsExcepttion(const std::string& vertex_name) : std::logic_error("Vertex '" + vertex_name + "' already exists.") {}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class VertexDoesNotExistExcepttion : public std::logic_error
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
VertexDoesNotExistExcepttion(const std::string& vertex_name) : std::logic_error("Vertex '" + vertex_name + "' does not exist.") {}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
|
|
struct Vertex;
|
|
|
|
struct Vertex;
|
|
|
@ -108,11 +120,11 @@ public:
|
|
|
|
|
|
|
|
|
|
|
|
/// @todo rename Vertex & Edge?
|
|
|
|
/// @todo rename Vertex & Edge?
|
|
|
|
// Modifiers
|
|
|
|
// Modifiers
|
|
|
|
bool addVertex(const_reference data);
|
|
|
|
void addVertex(const_reference data);
|
|
|
|
bool removeVertex(const_reference data);
|
|
|
|
void removeVertex(const_reference data);
|
|
|
|
bool addEdge(const_reference source, const_reference destination, const_weight_reference weight = weight_type());
|
|
|
|
void addEdge(const_reference source, const_reference destination, const_weight_reference weight = weight_type());
|
|
|
|
bool removeEdge(const_reference source, const_reference destination, const_weight_reference weight = weight_type());
|
|
|
|
void removeEdge(const_reference source, const_reference destination, const_weight_reference weight = weight_type());
|
|
|
|
bool removeAllEdges(const_reference source, const_reference destination);
|
|
|
|
void removeAllEdges(const_reference source, const_reference destination);
|
|
|
|
|
|
|
|
|
|
|
|
// Lookup
|
|
|
|
// Lookup
|
|
|
|
bool contains(const_reference data) const { return find(data) != m_vertices.end(); }
|
|
|
|
bool contains(const_reference data) const { return find(data) != m_vertices.end(); }
|
|
|
@ -211,6 +223,8 @@ public:
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
v_const_iterator find(const_reference data) const;
|
|
|
|
v_const_iterator find(const_reference data) const;
|
|
|
|
v_iterator find(const_reference data);
|
|
|
|
v_iterator find(const_reference data);
|
|
|
|
|
|
|
|
v_const_iterator findAndCheck(const_reference data, bool existence_expected = true) const;
|
|
|
|
|
|
|
|
v_iterator findAndCheck(const_reference data, bool existence_expected = true);
|
|
|
|
void adjustEdges(v_iterator vit);
|
|
|
|
void adjustEdges(v_iterator vit);
|
|
|
|
|
|
|
|
|
|
|
|
const bool m_directed;
|
|
|
|
const bool m_directed;
|
|
|
@ -402,21 +416,16 @@ inline typename Graph<V, E>::size_type Graph<V, E>::numberOfEdges() const
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
inline bool Graph<V, E>::addVertex(const_reference data)
|
|
|
|
inline void Graph<V, E>::addVertex(const_reference data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (find(data) != m_vertices.end())
|
|
|
|
findAndCheck(data, false);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_vertices.push_back(Vertex(data));
|
|
|
|
m_vertices.push_back(Vertex(data));
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
inline bool Graph<V, E>::removeVertex(const_reference data)
|
|
|
|
inline void Graph<V, E>::removeVertex(const_reference data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
v_iterator it = find(data);
|
|
|
|
v_iterator it = findAndCheck(data);
|
|
|
|
if (it == m_vertices.end())
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::for_each(m_vertices.begin(), m_vertices.end(),
|
|
|
|
std::for_each(m_vertices.begin(), m_vertices.end(),
|
|
|
|
[&it] (Vertex& v)
|
|
|
|
[&it] (Vertex& v)
|
|
|
@ -424,61 +433,39 @@ inline bool Graph<V, E>::removeVertex(const_reference data)
|
|
|
|
|
|
|
|
|
|
|
|
m_vertices.erase(it);
|
|
|
|
m_vertices.erase(it);
|
|
|
|
adjustEdges(it);
|
|
|
|
adjustEdges(it);
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
bool Graph<V, E>::addEdge(const_reference source, const_reference destination, const_weight_reference weight)
|
|
|
|
void Graph<V, E>::addEdge(const_reference source, const_reference destination, const_weight_reference weight)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
v_iterator source_it = find(source);
|
|
|
|
v_iterator source_it = findAndCheck(source);
|
|
|
|
if (source_it == m_vertices.end())
|
|
|
|
v_iterator destination_it = findAndCheck(destination);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v_iterator destination_it = find(destination);
|
|
|
|
|
|
|
|
if (destination_it == m_vertices.end())
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source_it->addEdge( v_iterator(destination_it), weight);
|
|
|
|
source_it->addEdge( v_iterator(destination_it), weight);
|
|
|
|
if (!m_directed)
|
|
|
|
if (!m_directed)
|
|
|
|
destination_it->addEdge( v_iterator(source_it), weight);
|
|
|
|
destination_it->addEdge( v_iterator(source_it), weight);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
inline bool Graph<V, E>::removeEdge(const_reference source, const_reference destination, const_weight_reference weight)
|
|
|
|
inline void Graph<V, E>::removeEdge(const_reference source, const_reference destination, const_weight_reference weight)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
v_iterator source_it = find(source);
|
|
|
|
v_iterator source_it = findAndCheck(source);
|
|
|
|
if (source_it == m_vertices.end())
|
|
|
|
v_iterator destination_it = findAndCheck(destination);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v_iterator destination_it = find(destination);
|
|
|
|
|
|
|
|
if (destination_it == m_vertices.end())
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source_it->removeEdge(destination, weight);
|
|
|
|
source_it->removeEdge(destination, weight);
|
|
|
|
if (!m_directed)
|
|
|
|
if (!m_directed)
|
|
|
|
destination_it->removeEdge(source, weight);
|
|
|
|
destination_it->removeEdge(source, weight);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
inline bool Graph<V, E>::removeAllEdges(const_reference source, const_reference destination)
|
|
|
|
inline void Graph<V, E>::removeAllEdges(const_reference source, const_reference destination)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
v_iterator source_it = find(source);
|
|
|
|
v_iterator source_it = findAndCheck(source);
|
|
|
|
if (source_it == m_vertices.end())
|
|
|
|
v_iterator destination_it = findAndCheck(destination);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v_iterator destination_it = find(destination);
|
|
|
|
|
|
|
|
if (destination_it == m_vertices.end())
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source_it->removeAllEdgesTo(destination_it);
|
|
|
|
source_it->removeAllEdgesTo(destination_it);
|
|
|
|
if (!m_directed)
|
|
|
|
if (!m_directed)
|
|
|
|
destination_it->removeAllEdgesTo(source_it);
|
|
|
|
destination_it->removeAllEdgesTo(source_it);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
@ -496,9 +483,7 @@ template <typename V, typename E>
|
|
|
|
std::vector<typename Graph<V, E>::value_type> Graph<V, E>::neighboursOf(const_reference data) const
|
|
|
|
std::vector<typename Graph<V, E>::value_type> Graph<V, E>::neighboursOf(const_reference data) const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
typename std::vector<value_type> retval;
|
|
|
|
typename std::vector<value_type> retval;
|
|
|
|
v_const_iterator vertex_it = find(data);
|
|
|
|
v_const_iterator vertex_it = findAndCheck(data);
|
|
|
|
if (vertex_it == m_vertices.end())
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::set<v_const_iterator> tmp;
|
|
|
|
std::set<v_const_iterator> tmp;
|
|
|
|
/// @todo rewrite for_each to parallel aware
|
|
|
|
/// @todo rewrite for_each to parallel aware
|
|
|
@ -514,9 +499,8 @@ template <typename V, typename E>
|
|
|
|
std::vector<E> Graph<V, E>::weightsBetween(const_reference source, const_reference destination) const
|
|
|
|
std::vector<E> Graph<V, E>::weightsBetween(const_reference source, const_reference destination) const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::vector<E> retval;
|
|
|
|
std::vector<E> retval;
|
|
|
|
v_const_iterator vertex_it = find(source);
|
|
|
|
v_const_iterator vertex_it = findAndCheck(source);
|
|
|
|
if (vertex_it == m_vertices.end())
|
|
|
|
findAndCheck(destination);
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// @todo rewrite for_each to parallel aware
|
|
|
|
/// @todo rewrite for_each to parallel aware
|
|
|
|
std::for_each(vertex_it->m_edges.begin(), vertex_it->m_edges.end(),
|
|
|
|
std::for_each(vertex_it->m_edges.begin(), vertex_it->m_edges.end(),
|
|
|
@ -552,7 +536,6 @@ Graph<V, E>::find(const_reference data) const
|
|
|
|
{ return v.m_data == data; });
|
|
|
|
{ return v.m_data == data; });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// @todo call the const it version
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
template <typename V, typename E>
|
|
|
|
inline typename Graph<V, E>::v_iterator
|
|
|
|
inline typename Graph<V, E>::v_iterator
|
|
|
|
Graph<V, E>::find(const_reference data)
|
|
|
|
Graph<V, E>::find(const_reference data)
|
|
|
@ -573,4 +556,32 @@ void Graph<V, E>::adjustEdges(v_iterator deleted_vit)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
|
|
|
|
typename Graph<V, E>::v_const_iterator
|
|
|
|
|
|
|
|
Graph<V, E>::findAndCheck(const_reference data, bool existence_expected) const
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
v_const_iterator it = find(data);
|
|
|
|
|
|
|
|
const bool found = (it != m_vertices.end());
|
|
|
|
|
|
|
|
if (!found && existence_expected)
|
|
|
|
|
|
|
|
throw VertexDoesNotExistExcepttion(data);
|
|
|
|
|
|
|
|
if (found && !existence_expected)
|
|
|
|
|
|
|
|
throw VertexAlreadyExistsExcepttion(data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return it;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename V, typename E>
|
|
|
|
|
|
|
|
typename Graph<V, E>::v_iterator
|
|
|
|
|
|
|
|
Graph<V, E>::findAndCheck(const_reference data, bool existence_expected)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
v_iterator it = find(data);
|
|
|
|
|
|
|
|
const bool found = (it != m_vertices.end());
|
|
|
|
|
|
|
|
if (!found && existence_expected)
|
|
|
|
|
|
|
|
throw VertexDoesNotExistExcepttion(data);
|
|
|
|
|
|
|
|
if (found && !existence_expected)
|
|
|
|
|
|
|
|
throw VertexAlreadyExistsExcepttion(data);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return it;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // GRAPH_H
|
|
|
|
#endif // GRAPH_H
|
|
|
|