88
99#include < stdio.h>
1010#include < list>
11+ #include < iostream>
1112
1213#include " GraphMatrix.h"
1314
14- GraphMatrix::Utils::Dijkstra::End::End (const uint32_t end, const int32_t score) :
15+ GraphMatrix::Utils::Dijkstra::End::End (const uint32_t end, const double score) :
1516 m_end(end),
1617 m_score(score)
1718{}
@@ -29,7 +30,20 @@ GraphMatrix::Utils::Dijkstra::End::End(End&& e)
2930 e.m_score = 0 ;
3031}
3132
32- GraphMatrix::Utils::Prim::Edge::Edge (const uint32_t begin, const uint32_t end, const int32_t cost) :
33+ GraphMatrix::Utils::Dijkstra::End& GraphMatrix::Utils::Dijkstra::End::operator =(End&& e)
34+ {
35+ if (this == &e)
36+ {
37+ return *this ;
38+ }
39+ m_end = e.m_end ;
40+ m_score = e.m_score ;
41+ e.m_end = 0 ;
42+ e.m_score = 0 ;
43+ return *this ;
44+ }
45+
46+ GraphMatrix::Utils::Prim::Edge::Edge (const uint32_t begin, const uint32_t end, const double cost) :
3347 m_begin(begin),
3448 m_end(end),
3549 m_cost(cost)
@@ -51,14 +65,29 @@ GraphMatrix::Utils::Prim::Edge::Edge(Edge&& e)
5165 e.m_cost = 0 ;
5266}
5367
68+ GraphMatrix::Utils::Prim::Edge& GraphMatrix::Utils::Prim::Edge::operator =(Edge&& e)
69+ {
70+ if (this == &e)
71+ {
72+ return *this ;
73+ }
74+ m_begin = e.m_begin ;
75+ m_end = e.m_end ;
76+ m_cost = e.m_cost ;
77+ e.m_begin = 0 ;
78+ e.m_end = 0 ;
79+ e.m_cost = 0 ;
80+ return *this ;
81+ }
82+
5483GraphMatrix::Utils::Prim::VertexCost::VertexCost ():
5584 m_set(false ),
5685 m_explored(false ),
5786 m_begin(0 ),
5887 m_cost(0 )
5988{}
6089
61- GraphMatrix::Utils::Prim::VertexCost::VertexCost (const uint32_t begin, const int32_t cost):
90+ GraphMatrix::Utils::Prim::VertexCost::VertexCost (const uint32_t begin, const double cost):
6291 m_set(true ),
6392 m_explored(false ),
6493 m_begin(begin),
@@ -77,6 +106,101 @@ GraphMatrix::Utils::Prim::VertexCost::VertexCost(VertexCost&& v)
77106 v.m_cost = 0 ;
78107}
79108
109+ GraphMatrix::Utils::Prim::VertexCost& GraphMatrix::Utils::Prim::VertexCost::operator =(VertexCost&& v)
110+ {
111+ if (this == &v)
112+ {
113+ return *this ;
114+ }
115+ m_set = v.m_set ;
116+ m_explored = v.m_explored ;
117+ m_begin = v.m_begin ;
118+ m_cost = v.m_cost ;
119+ v.m_set = false ;
120+ v.m_explored = false ;
121+ v.m_begin = 0 ;
122+ v.m_cost = 0 ;
123+ return *this ;
124+ }
125+
126+ GraphMatrix::Utils::BellmanFord::MinEntity::MinEntity () :
127+ m_length(0 ),
128+ m_infinity(true ),
129+ m_path(nullptr ),
130+ m_vertex(0 )
131+ {}
132+
133+ GraphMatrix::Utils::BellmanFord::MatrixEntity::MatrixEntity () :
134+ m_infinity(true ),
135+ m_path()
136+ {}
137+
138+ GraphMatrix::Utils::BellmanFord::MatrixEntity::~MatrixEntity ()
139+ {
140+ m_path.m_vertices .clear ();
141+ }
142+
143+ std::ostream& operator << (std::ostream& out, const GraphMatrix::Utils::BellmanFord::MatrixEntity& matrixEntity)
144+ {
145+ out << " [" << (matrixEntity.m_infinity ? " Infinity" : " Not infinity" ) << " : " << matrixEntity.m_path .m_length << " ]" ;
146+ return out;
147+ }
148+
149+ GraphMatrix::Path::Path () :
150+ m_length(0 ),
151+ m_vertices()
152+ {}
153+
154+ GraphMatrix::Path::Path (const Path& path)
155+ {
156+ m_length = path.m_length ;
157+ m_vertices = path.m_vertices ;
158+ }
159+
160+ GraphMatrix::Path::Path (Path&& path)
161+ {
162+ m_length = path.m_length ;
163+ m_vertices = std::move (path.m_vertices );
164+ path.m_length = 0 ;
165+ }
166+
167+ GraphMatrix::Path& GraphMatrix::Path::operator =(Path&& path)
168+ {
169+ if (this == &path)
170+ {
171+ return *this ;
172+ }
173+ m_length = path.m_length ;
174+ m_vertices = std::move (path.m_vertices );
175+ path.m_length = 0 ;
176+ return *this ;
177+ }
178+
179+ std::ostream& operator << (std::ostream& out, const GraphMatrix::Path& path)
180+ {
181+ out << " Length: " << path.m_length << ' \t ' << " Path: " ;
182+ bool first = true ;
183+ uint32_t prev = 0 ;
184+ for (auto v : path.m_vertices )
185+ {
186+ if (!first)
187+ {
188+ if (v != prev)
189+ {
190+ out << " -> " ;
191+ out << v + 1 ;
192+ }
193+ }
194+ else
195+ {
196+ out << v + 1 ;
197+ first = false ;
198+ }
199+ prev = v;
200+ }
201+ return out;
202+ }
203+
80204GraphMatrix::GraphMatrix ():
81205 m_numVertices(0 ),
82206 m_numEdges(0 ),
@@ -109,7 +233,7 @@ bool GraphMatrix::read(std::istream& in)
109233 // directed? begin end cost
110234 bool directed = false ;
111235 uint32_t begin = 0 , end = 0 ;
112- int32_t cost = 0 ;
236+ double cost = 0 ;
113237 in >> directed >> begin >> end >> cost;
114238 --begin;
115239 --end;
@@ -160,7 +284,7 @@ bool GraphMatrix::write(std::ostream& out)
160284 return true ;
161285}
162286
163- bool GraphMatrix::Dijkstra (uint32_t startingVertex, uint32_t endVertex, int32_t & length)
287+ bool GraphMatrix::Dijkstra (uint32_t startingVertex, uint32_t endVertex, double & length)
164288{
165289 if (startingVertex < 1 || endVertex < 1 ||
166290 startingVertex > m_numVertices || endVertex > m_numVertices)
@@ -273,7 +397,7 @@ bool GraphMatrix::MSTPrimStraightforward(GraphMatrix &mst)
273397 struct
274398 {
275399 bool m_set;
276- int32_t m_val;
400+ double m_val;
277401 uint32_t m_begin;
278402 uint32_t m_end;
279403 } min{false , 0 , 0 , 0 };
@@ -386,5 +510,81 @@ bool GraphMatrix::MSTPrim(GraphMatrix &mst)
386510 return false ;
387511 }
388512
513+ return true ;
514+ }
515+
516+ bool GraphMatrix::BellmandFord (uint32_t sourceVertex, std::vector<Path>& paths)
517+ {
518+ if ((sourceVertex < 1 ) ||
519+ (sourceVertex > m_numVertices))
520+ {
521+ return false ;
522+ }
523+ --sourceVertex;
524+
525+ Matrix<Utils::BellmanFord::MatrixEntity> matrix (m_numEdges + 1 , m_numVertices);
526+ matrix[0 ][sourceVertex].m_infinity = false ;
527+ matrix[0 ][sourceVertex].m_path .m_length = 0 ;
528+
529+ Utils::BellmanFord::MinEntity minEntity;
530+ for (uint32_t i = 1 ; i < m_numEdges + 1 ; ++i)
531+ {
532+ for (uint32_t v = 0 ; v < m_numVertices; ++v)
533+ {
534+ for (uint32_t w = 0 ; w < m_numVertices; ++w)
535+ {
536+ if (m_matrix[w][v].m_set && !matrix[i - 1 ][w].m_infinity )
537+ {
538+ if ((minEntity.m_infinity ) ||
539+ (matrix[i - 1 ][w].m_path .m_length + m_matrix[w][v].m_cost < minEntity.m_length ))
540+ {
541+ minEntity.m_infinity = false ;
542+ minEntity.m_length = matrix[i - 1 ][w].m_path .m_length + m_matrix[w][v].m_cost ;
543+ minEntity.m_path = &matrix[i - 1 ][w].m_path ;
544+ minEntity.m_vertex = w;
545+ }
546+ }
547+ }
548+ if (!matrix[i - 1 ][v].m_infinity )
549+ {
550+ if ((minEntity.m_infinity ) ||
551+ (matrix[i - 1 ][v].m_path .m_length < minEntity.m_length ))
552+ {
553+ minEntity.m_infinity = false ;
554+ minEntity.m_length = matrix[i - 1 ][v].m_path .m_length ;
555+ minEntity.m_path = &matrix[i - 1 ][v].m_path ;
556+ minEntity.m_vertex = v;
557+ }
558+ }
559+ // copy
560+ matrix[i][v].m_infinity = minEntity.m_infinity ;
561+ if (minEntity.m_path )
562+ {
563+ matrix[i][v].m_path = *minEntity.m_path ;
564+ matrix[i][v].m_path .m_vertices .push_back (minEntity.m_vertex );
565+ minEntity.m_path = nullptr ;
566+ minEntity.m_vertex = 0 ;
567+ }
568+ matrix[i][v].m_path .m_length = minEntity.m_length ;
569+ minEntity.m_infinity = true ;
570+ minEntity.m_length = 0 ;
571+ }
572+ }
573+
574+ for (uint32_t v = 0 ; v < m_numVertices; ++v)
575+ {
576+ if (matrix[m_numEdges][v].m_path .m_length < matrix[m_numEdges - 1 ][v].m_path .m_length )
577+ {
578+ // negative cycle was detected
579+ return false ;
580+ }
581+ }
582+
583+ for (uint32_t v = 0 ; v < m_numVertices; ++v)
584+ {
585+ matrix[m_numEdges - 1 ][v].m_path .m_vertices .push_back (v);
586+ paths.push_back (std::move (matrix[m_numEdges - 1 ][v].m_path ));
587+ }
588+
389589 return true ;
390590}
0 commit comments