Skip to content

Commit 0a4ff3a

Browse files
committed
Bellman-Ford algo for SSSP
1 parent 88bae2b commit 0a4ff3a

File tree

6 files changed

+286
-25
lines changed

6 files changed

+286
-25
lines changed

General/Matrix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Matrix
1515
uint64_t m_rowsCount;
1616
uint64_t m_colsCount;
1717

18-
std::unique_ptr<ValueType> m_matrix;
18+
std::unique_ptr<ValueType[]> m_matrix;
1919

2020
public:
2121
Matrix();

General/Matrix.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ void Matrix<T>::reset()
5858
template<typename T>
5959
void Matrix<T>::resize(uint64_t rowsCount, uint64_t colsCount)
6060
{
61-
std::unique_ptr<ValueType> matrix(new ValueType[rowsCount * colsCount]);
61+
std::unique_ptr<ValueType[]> matrix(new ValueType[rowsCount * colsCount]);
6262
uint64_t minColsCount = std::min(m_colsCount, colsCount);
6363
uint64_t minRowsCount = std::min(m_rowsCount, rowsCount);
6464
for (uint64_t i = 0; i < minRowsCount; ++i)

graphs/GraphMatrix.cpp

Lines changed: 206 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
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+
5483
GraphMatrix::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+
80204
GraphMatrix::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

Comments
 (0)