I need a graph for multiple pathfinding algorithms,so I wanted to ask whether my new graph implementation is ok. Would someone who works as a developer in related fields(Graphs, Pathfinding, Algorithms) do things similarly.
Node class:
#include "Coordinates.hpp"
#include <stdint.h>
namespace Pathfinding::Datastructures
{
struct Node
{
Node() = delete;
constexpr explicit Node(uint32_t i_ ) : id(i_) {};
uint32_t id;
};
[[nodiscard]] bool operator<(const Node & lhs, const Node & rhs);
[[nodiscard]] bool operator==(const Node & lhs, const Node & rhs);
}
Here is my graph.hpp:
#include <map>
#include <vector>
#include "Node.hpp"
#include "Connection.hpp"
namespace Pathfinding::Datastructures
{
class Graph
{
public:
Graph() = default;
void addConnection(Node start, Node goal, double weight);
[[nodiscard]] auto begin() { return data.begin(); }
[[nodiscard]] auto end() { return data.end(); }
[[nodiscard]] const auto begin() const { return data.begin(); }
[[nodiscard]] const auto end() const { return data.end(); }
[[nodiscard]] std::size_t size() const { return data.size(); }
[[nodiscard]] bool contains(Node node) const { return data.contains(node); }
[[nodiscard]] std::vector<Connection> operator[](Node node) const;
protected:
std::map<Node, std::vector<Connection>> data;
};
}
Graph.cpp:
#include "Graph.hpp"
#include <vector>
#include <exception>
#include "Connection.hpp"
#include "Node.hpp"
#include <iostream>
namespace Pathfinding::Datastructures
{
namespace
{
[[nodiscard]] bool nodeContainsConnection(const Graph & graph,
const Node & start, const Node & end)
{
for(const auto neighbor : graph[start])
{
if(neighbor.node == end)
{
return true;
}
}
return false;
}
}
void Graph::addConnection(Node start, Node goal, double weight)
{
if(data.contains(start))
{
if(!nodeContainsConnection(*this, start, goal))
{
data[start].push_back(Connection(goal, weight));
data[goal].push_back(Connection(start, weight));
}
}
else
{
data[start] = {Connection(goal, weight)};
data[goal] = {Connection(start, weight)};
}
}
std::vector<Connection> Graph::operator[](Node node) const
{
const auto it = data.find(node);
if(it == data.end())
{
throw std::exception("Node not present in graph");
}
return it->second;
}
}
Here is connection:
namespace Pathfinding::Datastructures
{
struct Connection
{
Connection() = delete;
Connection(Node node_, double weight_) : node(node_), weight(weight_) {}
Node node;
double weight;
};
[[nodiscard]] bool operator==(const Connection & lhs, const Connection & rhs);
}
Connection.cpp:
#include "Connection.hpp"
namespace Pathfinding::Datastructures
{
bool operator==(const Connection & lhs, const Connection & rhs)
{
return lhs.weight == rhs.weight && lhs.node == rhs.node;
}
}