Graph Cpp
Helper Graph class for C++ with CMake support
Loading...
Searching...
No Matches
Graph< vert_t, weight_t > Class Template Reference

Класс графа (может быть взвешенным и ориентированным). More...

#include <graph.hpp>

Collaboration diagram for Graph< vert_t, weight_t >:

Classes

class  Edge
 

Public Member Functions

 Graph ()
 Инициализирует новый экземпляр Graph.
 
 Graph (const Graph &other)=default
 Копирующий конструктор.
 
 Graph (Graph &&other) noexcept
 Перемещающий конструктор. Перемещает ресурсы из другого графа.
 
void AddEdge (const std::pair< vert_t, vert_t > &edge_pair, bool ignore_warning=false)
 
void AddEdge (const std::tuple< vert_t, vert_t, weight_t > &edge_tuple, bool ignore_warning=false)
 
void AddVert (const vert_t &vert)
 
bool ContainsEdge (const std::pair< vert_t, vert_t > &edge) const
 Проверяет, содержится ли ребро в графе (НЕВЗВЕШЕННЫЙ).
 
bool ContainsEdge (const std::tuple< vert_t, vert_t, weight_t > &edge) const
 Проверяет, содержится ли ребро в графе (ВЗВЕШЕННЫЙ).
 
bool ContainsVert (const vert_t &vert) const
 Проверяет, содержится ли вершина в графе.
 
std::vector< std::tuple< vert_t, vert_t, weight_t > > Edges () const
 
size_t EdgesAmount () const
 
std::unordered_map< vert_t, std::vector< vert_t > > GetAdjList () const
 
std::vector< std::vector< vert_t > > GetAdjListWithoutKeys () const
 
std::vector< std::vector< weight_t > > GetAdjMatrix () const
 
weight_t GetEdgeWeight (const std::pair< vert_t, vert_t > &edge) const
 Находит вес ребра в взвешенном графе.
 
bool IsDirected () const
 Проверяет, направлен ли граф.
 
bool IsWeighted () const
 Проверяет, взвешен ли граф.
 
void MakeDirected ()
 Делает граф направленным (ничего).
 
void MakeUndirected ()
 Делает граф ненаправленным (удаляет лишние ребра).
 
Graphoperator= (const Graph &other)=default
 Оператор копирующего присваивания.
 
Graphoperator= (Graph &&other) noexcept
 Оператор перемещающего присваивания. Перемещает ресурсы из другого. графа.
 
std::ostream & PrintAdjList (std::ostream &os=std::cout) const
 Выводит в поток список смежности.
 
std::ostream & PrintEdges (std::ostream &os=std::cout) const
 Выводит в поток список ребер.
 
std::ostream & PrintVerts (std::ostream &os=std::cout) const
 Выводит в поток список вершин.
 
void RemoveEdge (const std::pair< vert_t, vert_t > &edge_pair)
 
void RemoveEdge (const std::tuple< vert_t, vert_t, weight_t > &edge_tuple)
 
void RemoveVert (const vert_t &vert)
 
void SetEdgeWeight (const std::pair< vert_t, vert_t > &edge, weight_t new_weight)
 Меняет вес ребра в взвешенном графе.
 
const std::vector< vert_t > & Verts () const
 
size_t VertsAmount () const
 

Static Public Member Functions

static Graph GraphFromAdjList (const std::unordered_map< vert_t, std::vector< vert_t > > &adj_list_dict)
 Создает новый экземпляр Graph. по списку смежности с указанием вершины-ключа (НЕВЗВЕШЕННЫЙ).
 
static Graph GraphFromAdjList (const std::vector< std::vector< vert_t > > &adj_list)
 Создает новый экземпляр Graph. по списку смежности (НЕВЗВЕШЕННЫЙ).
 
static Graph GraphFromAdjMatrix (const std::vector< std::vector< weight_t > > &adj_matrix, bool is_weighted=false)
 Создает новый экземпляр Graph по матрице смежности.
 
static Graph GraphFromMap (const std::unordered_map< std::string, weight_t > &edges_dict)
 Создает новый экземпляр Graph по ребрам. представленными словарем из std::string и weight_t (ВЗВЕШЕННЫЙ).
 
static Graph GraphFromStrs (const std::vector< std::string > &edges_strs)
 Создает новый экземпляр Graph по ребрам. представленными вектором std::string (НЕВЗВЕШЕННЫЙ).
 
static Graph GraphNonWeighted (const std::vector< std::pair< vert_t, vert_t > > &edges_pairs)
 Создает новый экземпляр Graph по ребрам, представленными вектором std::pair (НЕВЗВЕШЕННЫЙ).
 
static Graph GraphWeighted (const std::vector< std::pair< vert_t, vert_t > > &edges_pairs, const std::vector< weight_t > &weights)
 Создает новый экземпляр Graph по ребрам, представленными вектором std::pair и weight_t (ВЗВЕШЕННЫЙ).
 
static Graph GraphWeighted (const std::vector< std::tuple< vert_t, vert_t, weight_t > > &edges_tuples)
 Создает новый экземпляр Graph по ребрам. представленными вектором std::tuple (ВЗВЕШЕННЫЙ).
 

Private Member Functions

 Graph (const std::vector< Edge > &edges)
 
void AddEdge_ (const Edge &edge)
 
auto GetEdgeIter_ (const std::pair< vert_t, vert_t > &edge)
 
auto GetEdgeIter_ (const std::pair< vert_t, vert_t > &edge) const
 
auto GetEdgeIter_ (const std::tuple< vert_t, vert_t, weight_t > &edge) const
 

Static Private Member Functions

static std::pair< vert_t, vert_t > ParseEdgeString_ (const std::string &edge_str)
 

Private Attributes

std::vector< Edgeedges_
 
bool is_direct_ = true
 
bool is_weighted_ = false
 
std::vector< vert_t > verts_
 

Friends

std::ostream & operator<< (std::ostream &os, const Graph< vert_t, weight_t >::Edge &edge)
 

Detailed Description

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
class Graph< vert_t, weight_t >

Класс графа (может быть взвешенным и ориентированным).

Template Parameters
vert_tтип вершин.
weight_tтип весов.

Constructor & Destructor Documentation

◆ Graph() [1/4]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph< vert_t, weight_t >::Graph ( )
inline

Инициализирует новый экземпляр Graph.

47: edges_(), verts_() {}
std::vector< Edge > edges_
Definition graph.hpp:736
std::vector< vert_t > verts_
Definition graph.hpp:737
Here is the caller graph for this function:

◆ Graph() [2/4]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph< vert_t, weight_t >::Graph ( const Graph< vert_t, weight_t > & other)
default

Копирующий конструктор.

Parameters
otherграф, который нужно скопировать.

◆ Graph() [3/4]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph< vert_t, weight_t >::Graph ( Graph< vert_t, weight_t > && other)
inlinenoexcept

Перемещающий конструктор. Перемещает ресурсы из другого графа.

Parameters
otherграф, ресурсы которого нужно переместить.
71 : edges_(std::move(other.edges_)),
72 verts_(std::move(other.verts_)),
73 is_direct_{other.is_direct_} {}
bool is_direct_
Definition graph.hpp:739

◆ Graph() [4/4]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph< vert_t, weight_t >::Graph ( const std::vector< Edge > & edges)
inlineprivate
750 {
751 if (edges.empty()) return;
752
753 for (const auto& edge : edges) {
754 if (edge.IsWeighted()) is_weighted_ = true;
755 AddEdge_(edge);
756 }
757
758 if constexpr (std::is_arithmetic_v<vert_t>) {
759 // кол-во вершин = максимальная вершина среди ребер, т.е. в этом случае
760 // происходит заполнение вершин до наибольшей из них в списке ребер
761 vert_t max_vert = edges[0].StartVert();
762
763 for (const auto& edge : edges_) {
764 max_vert = std::max(max_vert, edge.StartVert());
765 max_vert = std::max(max_vert, edge.EndVert());
766 }
767
768 verts_.resize(max_vert + 1);
769 std::iota(verts_.begin(), verts_.end(), 0);
770
771 } else if constexpr (std::is_same_v<vert_t, std::string>)
772 for (const auto& edge : edges_) {
773 if (!Contains(Verts(), edge.StartVert()))
774 verts_.push_back(edge.StartVert());
775
776 if (!Contains(Verts(), edge.EndVert()))
777 verts_.push_back(edge.EndVert());
778 }
779 }
void AddEdge_(const Edge &edge)
Definition graph.hpp:781
const std::vector< vert_t > & Verts() const
Definition graph.hpp:326
bool is_weighted_
Definition graph.hpp:740
bool Contains(const std::vector< T > &vec, const T &value)
Проверяет наличие элемента в векторе.
Definition utils.hpp:193
Here is the call graph for this function:

Member Function Documentation

◆ AddEdge() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::AddEdge ( const std::pair< vert_t, vert_t > & edge_pair,
bool ignore_warning = false )
inline
Warning
"AddEdge: weighted graph must consist of weighted edges.
587 {
588 if (IsWeighted() && !ignore_warning)
589 std::cerr << "Warning! AddEdge: weighted graph should consist of "
590 "weighted edges."
591 << std::endl;
592
593 AddEdge_(Edge(edge_pair.first, edge_pair.second, static_cast<weight_t>(0)));
594 }
bool IsWeighted() const
Проверяет, взвешен ли граф.
Definition graph.hpp:317
Here is the call graph for this function:

◆ AddEdge() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::AddEdge ( const std::tuple< vert_t, vert_t, weight_t > & edge_tuple,
bool ignore_warning = false )
inline
Warning
"AddEdge: weighted graph must consist of weighted edges.
577 {
578 if (WeightFromTuple(edge_tuple) == 0)
579 AddEdge({StartVertFromTuple(edge_tuple), EndVertFromTuple(edge_tuple)},
580 ignore_warning);
581 else
582 AddEdge_(edge_tuple);
583 }
void AddEdge(const std::tuple< vert_t, vert_t, weight_t > &edge_tuple, bool ignore_warning=false)
Definition graph.hpp:576
vert_t EndVertFromTuple(const std::tuple< vert_t, vert_t, weight_t > &edge)
Definition graph.hpp:23
weight_t WeightFromTuple(const std::tuple< vert_t, vert_t, weight_t > &edge)
Definition graph.hpp:29
vert_t StartVertFromTuple(const std::tuple< vert_t, vert_t, weight_t > &edge)
Definition graph.hpp:17
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddEdge_()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::AddEdge_ ( const Edge & edge)
inlineprivate
781 {
782 AddVert(edge.StartVert());
783 AddVert(edge.EndVert());
784
785 if (!Contains(edges_, edge)) edges_.emplace_back(edge);
786
787 if (edge.Weight() != 0) is_weighted_ = true;
788 }
void AddVert(const vert_t &vert)
Definition graph.hpp:571
Here is the call graph for this function:
Here is the caller graph for this function:

◆ AddVert()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::AddVert ( const vert_t & vert)
inline
571 {
572 if (!Contains(verts_, vert)) verts_.push_back(vert);
573 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ContainsEdge() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::ContainsEdge ( const std::pair< vert_t, vert_t > & edge) const
inline

Проверяет, содержится ли ребро в графе (НЕВЗВЕШЕННЫЙ).

Parameters
edgeребро.
Returns
true: содержится.
false: не содержится.
521 {
522 return GetEdgeIter_(edge) != edges_.end();
523 }
auto GetEdgeIter_(const std::pair< vert_t, vert_t > &edge) const
Definition graph.hpp:822
Here is the call graph for this function:

◆ ContainsEdge() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::ContainsEdge ( const std::tuple< vert_t, vert_t, weight_t > & edge) const
inline

Проверяет, содержится ли ребро в графе (ВЗВЕШЕННЫЙ).

Parameters
edgeребро.
Returns
true: содержится.
false: не содержится.
Exceptions
`std::logic_error("ContainsEdgegraph is not weighted.")`.
506 {
507 if (!IsWeighted())
508 throw std::logic_error("ContainsEdge: graph is not weighted.");
509
510 return GetEdgeIter_(edge) != edges_.end();
511 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ContainsVert()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::ContainsVert ( const vert_t & vert) const
inline

Проверяет, содержится ли вершина в графе.

Parameters
vertвершина.
Returns
true: содержится.
false: не содержится.
492 {
493 return std::find(Verts().begin(), Verts().end(), vert) != Verts().end();
494 }
Here is the call graph for this function:

◆ Edges()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::vector< std::tuple< vert_t, vert_t, weight_t > > Graph< vert_t, weight_t >::Edges ( ) const
inline
Returns
std::vector<std::tuple<vert_t, vert_t, weight_t>>: ребра.
329 {
330 if (edges_.empty()) return {};
331
332 std::vector<std::tuple<vert_t, vert_t, weight_t>> edges_tuples(
333 edges_.size());
334 std::transform(edges_.begin(), edges_.end(), edges_tuples.begin(),
335 [](const Edge& edge) {
336 return std::make_tuple(edge.StartVert(), edge.EndVert(),
337 edge.Weight());
338 });
339
340 return edges_tuples;
341 }

◆ EdgesAmount()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
size_t Graph< vert_t, weight_t >::EdgesAmount ( ) const
inline
Returns
vert_t: кол-во ребер.
323{ return edges_.size(); }
Here is the caller graph for this function:

◆ GetAdjList()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::unordered_map< vert_t, std::vector< vert_t > > Graph< vert_t, weight_t >::GetAdjList ( ) const
inline
Returns
std::unordered_map<vert_t, std::vector<vert_t>>: список смежности с указанием вершины-ключа.
444 {
445 auto adj_list_dict = std::unordered_map<vert_t, std::vector<vert_t>>();
446
447 for (const auto& edge : edges_) {
448 adj_list_dict[edge.StartVert()].push_back(edge.EndVert());
449 if (!IsDirected())
450 adj_list_dict[edge.EndVert()].push_back(edge.StartVert());
451 }
452
453 return adj_list_dict;
454 }
bool IsDirected() const
Проверяет, направлен ли граф.
Definition graph.hpp:417
Here is the call graph for this function:

◆ GetAdjListWithoutKeys()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::vector< std::vector< vert_t > > Graph< vert_t, weight_t >::GetAdjListWithoutKeys ( ) const
inline
Returns
std::vector<std::vector<vert_t>>: список смежности.
Exceptions
`std::logic_error("GetAdjListWithoutKeysthis method is deleted for std::string.")`.
424 {
425 if constexpr (std::is_arithmetic_v<vert_t>) {
426 std::vector<std::vector<vert_t>> adj_list(
427 *std::max_element(Verts().begin(), Verts().end()) + 1);
428
429 for (const auto& edge : edges_) {
430 adj_list[edge.StartVert()].push_back(edge.EndVert());
431 if (!IsDirected()) adj_list[edge.EndVert()].push_back(edge.StartVert());
432 }
433
434 return adj_list;
435 }
436
437 else if constexpr (std::is_same_v<vert_t, std::string>)
438 throw std::logic_error(
439 "GetAdjListWithoutKeys: this method is deleted for std::string.");
440 }
Here is the call graph for this function:

◆ GetAdjMatrix()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::vector< std::vector< weight_t > > Graph< vert_t, weight_t >::GetAdjMatrix ( ) const
inline
Returns
std::vector<std::vector<vert_t>>: матрица смежности.
Exceptions
`std::logic_error("GetAdjMatrixthis method is deleted for std::string.")`.
461 {
462 if constexpr (std::is_arithmetic_v<vert_t>) {
463 std::vector<std::vector<weight_t>> adj_matrix(
464 VertsAmount(), std::vector<weight_t>(VertsAmount(), 0));
465
466 for (const auto& edge : edges_)
467 if (edge.IsWeighted()) {
468 adj_matrix[edge.StartVert()][edge.EndVert()] = edge.Weight();
469 if (!IsDirected())
470 adj_matrix[edge.EndVert()][edge.StartVert()] = edge.Weight();
471 } else {
472 adj_matrix[edge.StartVert()][edge.EndVert()] = 1;
473 if (!IsDirected()) adj_matrix[edge.EndVert()][edge.StartVert()] = 1;
474 }
475
476 return adj_matrix;
477 }
478
479 else if constexpr (std::is_same_v<vert_t, std::string>)
480 throw std::logic_error(
481 "GetAdjMatrix: this method is deleted for std::string.");
482 }
size_t VertsAmount() const
Definition graph.hpp:320
Here is the call graph for this function:

◆ GetEdgeIter_() [1/3]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
auto Graph< vert_t, weight_t >::GetEdgeIter_ ( const std::pair< vert_t, vert_t > & edge)
inlineprivate
834 {
835 auto [start_vert, end_vert] = edge;
836
837 return std::find_if(
838 edges_.begin(), edges_.end(),
839 [start_vert, end_vert, this](const auto& e) {
840 return (e.StartVert() == start_vert && e.EndVert() == end_vert) ||
841 (!IsDirected() && e.StartVert() == end_vert &&
842 e.EndVert() == start_vert);
843 });
844 }

◆ GetEdgeIter_() [2/3]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
auto Graph< vert_t, weight_t >::GetEdgeIter_ ( const std::pair< vert_t, vert_t > & edge) const
inlineprivate
822 {
823 auto [start_vert, end_vert] = edge;
824
825 return std::find_if(
826 edges_.begin(), edges_.end(),
827 [start_vert, end_vert, this](const auto& e) {
828 return (e.StartVert() == start_vert && e.EndVert() == end_vert) ||
829 (!IsDirected() && e.StartVert() == end_vert &&
830 e.EndVert() == start_vert);
831 });
832 }
Here is the caller graph for this function:

◆ GetEdgeIter_() [3/3]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
auto Graph< vert_t, weight_t >::GetEdgeIter_ ( const std::tuple< vert_t, vert_t, weight_t > & edge) const
inlineprivate
846 {
847 auto [start_vert, end_vert, weight] = edge;
848
849 return std::find_if(
850 edges_.begin(), edges_.end(),
851 [start_vert, end_vert, weight, this](const auto& e) {
852 return (e.StartVert() == start_vert && e.EndVert() == end_vert &&
853 e.Weight() == weight) ||
854 (!IsDirected() && e.StartVert() == end_vert &&
855 e.EndVert() == start_vert && e.Weight() == weight);
856 });
857 }

◆ GetEdgeWeight()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
weight_t Graph< vert_t, weight_t >::GetEdgeWeight ( const std::pair< vert_t, vert_t > & edge) const
inline

Находит вес ребра в взвешенном графе.

Parameters
edgeребро.
Returns
weight_t: вес.
Exceptions
`std::logic_error("GetEdgeWeightgraph is not weighted.")`. @throw `std::invalid_argument("GetEdgeWeight: there is no such edge:")`.
535 {
536 if (!IsWeighted())
537 throw std::logic_error("GetEdgeWeight: graph is not weighted.");
538
539 auto it = GetEdgeIter_(edge);
540
541 if (it == edges_.end())
542 throw std::invalid_argument("GetEdgeWeight: there is no such edge: " +
543 Edge(edge).Name());
544
545 return it->Weight();
546 }
Here is the call graph for this function:

◆ GraphFromAdjList() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphFromAdjList ( const std::unordered_map< vert_t, std::vector< vert_t > > & adj_list_dict)
inlinestatic

Создает новый экземпляр Graph. по списку смежности с указанием вершины-ключа (НЕВЗВЕШЕННЫЙ).

Parameters
adj_list_dictсписок смежности с указанием вершины-ключа.
Returns
Graph: новый экземпляр Graph.
302 {
303 if (adj_list_dict.empty()) return Graph();
304
305 std::vector<Edge> edges{};
306
307 for (const auto& vert_str_pair : adj_list_dict) {
308 auto vert = vert_str_pair.first;
309 for (const auto& vert_2 : vert_str_pair.second)
310 edges.push_back(Edge(vert, vert_2));
311 }
312
313 return Graph(edges);
314 }
Graph()
Инициализирует новый экземпляр Graph.
Definition graph.hpp:47
Here is the call graph for this function:

◆ GraphFromAdjList() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphFromAdjList ( const std::vector< std::vector< vert_t > > & adj_list)
inlinestatic

Создает новый экземпляр Graph. по списку смежности (НЕВЗВЕШЕННЫЙ).

Parameters
adj_listсписок смежности.
Returns
Graph: новый экземпляр Graph.
Exceptions
std::logic_error("GraphFromAdjListthis method (constructor) is deleted for std::string.").
275 {
276 if constexpr (std::is_arithmetic_v<vert_t>) {
277 if (adj_list.empty()) return Graph();
278
279 std::vector<Edge> edges{};
280
281 for (size_t row = 0; row < adj_list.size(); row++)
282 for (size_t col = 0; col < adj_list[row].size(); col++)
283 edges.push_back(Edge(row, adj_list[row][col]));
284
285 return Graph(edges);
286
287 } else if constexpr (std::is_same_v<vert_t, std::string>)
288 throw std::logic_error(
289 "GraphFromAdjList: this method (constructor) "
290 "is deleted for std::string.");
291 }
Here is the call graph for this function:

◆ GraphFromAdjMatrix()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphFromAdjMatrix ( const std::vector< std::vector< weight_t > > & adj_matrix,
bool is_weighted = false )
inlinestatic

Создает новый экземпляр Graph по матрице смежности.

Parameters
adj_matrixматрица смежности.
is_weightedвзвешен ли граф.
Returns
Graph: новый экземпляр Graph.
Exceptions
`std::invalid_argument("GraphFromAdjMatrixAdjacencyMatrix is not squared.")`. @throw `std::invalid_argument("GraphFromAdjMatrix: AdjacencyMatrix is not squared [row problem].")`. @throw `std::logic_error("GraphFromAdjMatrix: this method (constructor) is deleted for std::string.")`.
228 {
229 if constexpr (std::is_arithmetic_v<vert_t>) {
230 if (adj_matrix.empty()) return Graph();
231
232 std::vector<Edge> edges{};
233
234 if (adj_matrix.size() != adj_matrix[0].size())
235 throw std::invalid_argument(
236 "GraphFromAdjMatrix: AdjacencyMatrix is not squared.");
237
238 for (size_t row = 0; row < adj_matrix.size(); row++) {
239 if (row != 0)
240 if (adj_matrix[row].size() != adj_matrix[row - 1].size())
241 throw std::invalid_argument(
242 "GraphFromAdjMatrix: AdjacencyMatrix is not squared [row "
243 "problem].");
244
245 for (size_t col = 0; col < adj_matrix[row].size(); col++) {
246 if (adj_matrix[row][col] == 0) continue;
247
248 if (is_weighted)
249 edges.push_back(Edge(col, row, adj_matrix[col][row]));
250 else
251 edges.push_back(Edge(col, row));
252 }
253 }
254
255 return Graph(edges);
256
257 } else if constexpr (std::is_same_v<vert_t, std::string>)
258 throw std::logic_error(
259 "GraphFromAdjMatrix: this method (constructor) "
260 "is deleted for std::string.");
261 }
Here is the call graph for this function:

◆ GraphFromMap()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphFromMap ( const std::unordered_map< std::string, weight_t > & edges_dict)
inlinestatic

Создает новый экземпляр Graph по ребрам. представленными словарем из std::string и weight_t (ВЗВЕШЕННЫЙ).

Parameters
edges_dictребра графа.
Returns
Graph: новый экземпляр Graph.
196 {
197 if (edges_dict.empty()) return Graph();
198
199 std::vector<Graph<vert_t, weight_t>::Edge> edges;
200
201 for (const auto& [edge_str, weight] : edges_dict) {
202 vert_t start_vert, end_vert;
203 std::tie(start_vert, end_vert) = ParseEdgeString_(edge_str);
204
205 edges.emplace_back(start_vert, end_vert, weight);
206 }
207
208 return Graph(edges);
209 }
static std::pair< vert_t, vert_t > ParseEdgeString_(const std::string &edge_str)
Definition graph.hpp:790
Here is the call graph for this function:

◆ GraphFromStrs()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphFromStrs ( const std::vector< std::string > & edges_strs)
inlinestatic

Создает новый экземпляр Graph по ребрам. представленными вектором std::string (НЕВЗВЕШЕННЫЙ).

Parameters
edges_strsребра графа.
Returns
Graph: новый экземпляр Graph.
172 {
173 if (edges_strs.empty()) return Graph();
174
175 std::vector<Graph<vert_t, weight_t>::Edge> edges;
176
177 for (const auto& edge_str : edges_strs) {
178 vert_t start_vert, end_vert;
179 std::tie(start_vert, end_vert) = ParseEdgeString_(edge_str);
180
181 edges.emplace_back(start_vert, end_vert);
182 }
183
184 return Graph(edges);
185 }
Here is the call graph for this function:

◆ GraphNonWeighted()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphNonWeighted ( const std::vector< std::pair< vert_t, vert_t > > & edges_pairs)
inlinestatic

Создает новый экземпляр Graph по ребрам, представленными вектором std::pair (НЕВЗВЕШЕННЫЙ).

Parameters
edges_pairsребра графа.
Returns
Graph: новый экземпляр Graph.
102 {
103 if (edges_pairs.empty()) return Graph();
104
105 std::vector<Edge> edges{};
106 edges.reserve(edges_pairs.size());
107
108 for (const auto& edge : edges_pairs) edges.push_back(edge);
109
110 return Graph(edges);
111 }
Here is the call graph for this function:

◆ GraphWeighted() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphWeighted ( const std::vector< std::pair< vert_t, vert_t > > & edges_pairs,
const std::vector< weight_t > & weights )
inlinestatic

Создает новый экземпляр Graph по ребрам, представленными вектором std::pair и weight_t (ВЗВЕШЕННЫЙ).

Parameters
edges_pairsребра графа.
weightsвеса ребер.
Returns
Graph: новый экземпляр Graph.
Exceptions
`std::invalid_argument("GraphWeightedthe sizes of the edges and weights vectors do not match.")`.
127 {
128 if (edges_pairs.empty() && weights.empty()) return Graph();
129
130 std::vector<Edge> edges{};
131 edges.reserve(edges_pairs.size());
132
133 if (edges_pairs.size() != weights.size())
134 throw std::invalid_argument(
135 "GraphWeighted: the sizes of the edges and weights vectors do not "
136 "match.");
137
138 for (size_t i = 0; i < weights.size(); i++)
139 edges.push_back(Edge(edges_pairs[i], weights[i]));
140
141 return Graph(edges);
142 }
Here is the call graph for this function:

◆ GraphWeighted() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static Graph Graph< vert_t, weight_t >::GraphWeighted ( const std::vector< std::tuple< vert_t, vert_t, weight_t > > & edges_tuples)
inlinestatic

Создает новый экземпляр Graph по ребрам. представленными вектором std::tuple (ВЗВЕШЕННЫЙ).

Parameters
edges_tuplesребра графа.
Returns
Graph: новый экземпляр Graph.
153 {
154 if (edges_tuples.empty()) return Graph();
155
156 std::vector<Edge> edges;
157
158 for (const auto& [start, end, weight] : edges_tuples)
159 edges.emplace_back(start, end, weight);
160
161 return Graph(edges);
162 }
Here is the call graph for this function:

◆ IsDirected()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::IsDirected ( ) const
inline

Проверяет, направлен ли граф.

417{ return is_direct_; }
Here is the caller graph for this function:

◆ IsWeighted()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::IsWeighted ( ) const
inline

Проверяет, взвешен ли граф.

317{ return is_weighted_; }
Here is the caller graph for this function:

◆ MakeDirected()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::MakeDirected ( )
inline

Делает граф направленным (ничего).

414{ is_direct_ = true; }

◆ MakeUndirected()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::MakeUndirected ( )
inline

Делает граф ненаправленным (удаляет лишние ребра).

391 {
392 std::unordered_set<size_t> seen_edges;
393 std::vector<Edge> unique_edges;
394 unique_edges.reserve(EdgesAmount());
395
396 for (size_t i = 0; i < EdgesAmount(); i++) {
397 if (seen_edges.count(i) != 0) continue;
398
399 for (size_t j = i + 1; j < EdgesAmount(); j++)
400 if (edges_[i].StartVert() == edges_[j].EndVert() &&
401 edges_[j].StartVert() == edges_[i].EndVert()) {
402 seen_edges.insert(j);
403 break;
404 }
405
406 unique_edges.push_back(edges_[i]);
407 }
408
409 edges_ = std::move(unique_edges);
410 is_direct_ = false;
411 }
size_t EdgesAmount() const
Definition graph.hpp:323
Here is the call graph for this function:

◆ operator=() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph & Graph< vert_t, weight_t >::operator= ( const Graph< vert_t, weight_t > & other)
default

Оператор копирующего присваивания.

Parameters
otherграф, значения которого нужно присвоить.
Returns
Graph&: ссылка на текущий объект.

◆ operator=() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
Graph & Graph< vert_t, weight_t >::operator= ( Graph< vert_t, weight_t > && other)
inlinenoexcept

Оператор перемещающего присваивания. Перемещает ресурсы из другого. графа.

Parameters
otherграф, ресурсы которого нужно переместить.
Returns
Graph&: ссылка на текущий объект.
83 {
84 if (this != &other) {
85 edges_ = std::move(other.edges_);
86 verts_ = std::move(other.verts_);
87 is_direct_ = other.is_direct_;
88 }
89
90 return *this;
91 }

◆ ParseEdgeString_()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
static std::pair< vert_t, vert_t > Graph< vert_t, weight_t >::ParseEdgeString_ ( const std::string & edge_str)
inlinestaticprivate
791 {
792 const size_t pos = edge_str.find("->");
793 vert_t start_vert;
794 vert_t end_vert;
795
796 if (pos == std::string::npos)
797 throw std::invalid_argument("EdgeString: invalid edge string format: " +
798 edge_str);
799
800 if constexpr (std::is_arithmetic_v<vert_t>) {
801 try {
802 start_vert = std::stoul(edge_str.substr(0, pos));
803 end_vert = std::stoul(edge_str.substr(pos + 2));
804 }
805
806 catch (const std::exception&) {
807 throw std::invalid_argument(
808 "EdgeString: invalid edge string format "
809 "(vertices should be numbers): " +
810 edge_str);
811 }
812 }
813
814 else if constexpr (std::is_same_v<vert_t, std::string>) {
815 start_vert = edge_str.substr(0, pos);
816 end_vert = edge_str.substr(pos + 2);
817 }
818
819 return {start_vert, end_vert};
820 }
Here is the caller graph for this function:

◆ PrintAdjList()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::ostream & Graph< vert_t, weight_t >::PrintAdjList ( std::ostream & os = std::cout) const
inline

Выводит в поток список смежности.

Parameters
osвходной поток.
Returns
std::ostream&: выходной поток.
374 {
375 for (const auto& vert : Verts()) {
376 os << vert << ": ";
377
378 for (const auto& neighbor : edges_) {
379 if (neighbor.StartVert() == vert) os << neighbor.EndVert() << "; ";
380 if (!IsDirected())
381 if (neighbor.EndVert() == vert) os << neighbor.StartVert() << "; ";
382 }
383
384 os << "\n";
385 }
386
387 return os;
388 }
Here is the call graph for this function:

◆ PrintEdges()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::ostream & Graph< vert_t, weight_t >::PrintEdges ( std::ostream & os = std::cout) const
inline

Выводит в поток список ребер.

Parameters
osвходной поток.
Returns
std::ostream&: выходной поток.
362 {
363 os << edges_;
364 return os;
365 }
Here is the caller graph for this function:

◆ PrintVerts()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::ostream & Graph< vert_t, weight_t >::PrintVerts ( std::ostream & os = std::cout) const
inline

Выводит в поток список вершин.

Parameters
osвходной поток.
Returns
std::ostream&: выходной поток.
350 {
351 os << Verts();
352 return os;
353 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveEdge() [1/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::RemoveEdge ( const std::pair< vert_t, vert_t > & edge_pair)
inline
Exceptions
`std::invalid_argument("RemoveEdgethere is no such edge:")`.
621 {
622 if (!ContainsEdge(edge_pair))
623 throw std::invalid_argument(
624 "RemoveEdge: there is no such edge in graph: " +
625 Edge(edge_pair).Name());
626
627 edges_.erase(std::remove_if(edges_.begin(), edges_.end(),
628 [&edge_pair, this](const Edge& e) {
629 return (e == Edge(edge_pair)) ||
630 (!IsDirected() &&
631 Edge(e.EndVert(), e.StartVert()) ==
632 Edge(edge_pair));
633 }),
634 edges_.end());
635 }
bool ContainsEdge(const std::tuple< vert_t, vert_t, weight_t > &edge) const
Проверяет, содержится ли ребро в графе (ВЗВЕШЕННЫЙ).
Definition graph.hpp:506
Here is the call graph for this function:

◆ RemoveEdge() [2/2]

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::RemoveEdge ( const std::tuple< vert_t, vert_t, weight_t > & edge_tuple)
inline
Exceptions
`std::invalid_argument("RemoveEdgethere is no such edge:")`.
638 {
639 if (!ContainsEdge(edge_tuple))
640 throw std::invalid_argument(
641 "RemoveEdge: there is no such edge in graph: " +
642 Edge(edge_tuple).Name());
643
644 edges_.erase(
645 std::remove_if(
646 edges_.begin(), edges_.end(),
647 [&edge_tuple, this](const Edge& e) {
648 return (e == Edge(edge_tuple)) ||
649 (!IsDirected() &&
650 e == Edge(std::make_tuple(EndVertFromTuple(edge_tuple),
651 StartVertFromTuple(edge_tuple),
652 WeightFromTuple(edge_tuple))));
653 }),
654 edges_.end());
655 }
Here is the call graph for this function:

◆ RemoveVert()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::RemoveVert ( const vert_t & vert)
inline
Exceptions
`std::invalid_argument("RemoveVertthere is no such vert:")`.
597 {
598 if constexpr (std::is_arithmetic_v<vert_t>) {
599 if (!Contains(Verts(), vert))
600 throw std::invalid_argument(
601 "RemoveVert: there is no such vert in graph: " +
602 std::to_string(vert));
603 }
604
605 else if constexpr (std::is_same_v<vert_t, std::string>)
606 if (!Contains(Verts(), vert))
607 throw std::invalid_argument(
608 "RemoveVert: there is no such vert in graph: " + vert);
609
610 verts_.erase(std::remove(verts_.begin(), verts_.end(), vert), verts_.end());
611
612 edges_.erase(std::remove_if(edges_.begin(), edges_.end(),
613 [vert](const Edge& edge) {
614 return edge.StartVert() == vert ||
615 edge.EndVert() == vert;
616 }),
617 edges_.end());
618 }
Here is the call graph for this function:

◆ SetEdgeWeight()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
void Graph< vert_t, weight_t >::SetEdgeWeight ( const std::pair< vert_t, vert_t > & edge,
weight_t new_weight )
inline

Меняет вес ребра в взвешенном графе.

Parameters
edgeребро.
new_weightвес.
Exceptions
`std::logic_error("SetEdgeWeightgraph is not weighted.")`. @throw `std::invalid_argument("SetEdgeWeight: there is no such edge:")`.
558 {
559 if (!IsWeighted())
560 throw std::logic_error("SetEdgeWeight: graph is not weighted.");
561
562 auto it = GetEdgeIter_(edge);
563
564 if (it == edges_.end())
565 throw std::invalid_argument("SetEdgeWeight: there is no such edge: " +
566 Edge(edge).Name());
567
568 it->SetWeight(new_weight);
569 }
Here is the call graph for this function:

◆ Verts()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
const std::vector< vert_t > & Graph< vert_t, weight_t >::Verts ( ) const
inline
Returns
const std::vector<vert_t>&: вершины.
326{ return verts_; }
Here is the caller graph for this function:

◆ VertsAmount()

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
size_t Graph< vert_t, weight_t >::VertsAmount ( ) const
inline
Returns
size_t: кол-во вершин.
320{ return verts_.size(); }
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ operator<<

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::ostream & operator<< ( std::ostream & os,
const Graph< vert_t, weight_t >::Edge & edge )
friend
744 {
745 os << edge.Name();
746 return os;
747 }
const std::string & Name() const
Definition graph.hpp:703

Member Data Documentation

◆ edges_

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::vector<Edge> Graph< vert_t, weight_t >::edges_
private

◆ is_direct_

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::is_direct_ = true
private

◆ is_weighted_

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
bool Graph< vert_t, weight_t >::is_weighted_ = false
private

◆ verts_

template<AllowedVertType vert_t = std::string, AllowedWeightType weight_t = size_t>
std::vector<vert_t> Graph< vert_t, weight_t >::verts_
private

The documentation for this class was generated from the following file: