Shortest path found
This commit is contained in:
@@ -1,56 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <deque>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace daggy {
|
||||
|
||||
template<typename I, typename T>
|
||||
template<typename T>
|
||||
class DAG {
|
||||
public:
|
||||
DAG() {}
|
||||
|
||||
void addVertex(I id, T && data);
|
||||
void dropVertex(I id);
|
||||
void updateVertex(I id, T && data);
|
||||
void addVertex(T id);
|
||||
void dropVertex(const T & id);
|
||||
|
||||
void addEdge(I src, I dst);
|
||||
void dropEdge(I src, I dst);
|
||||
void addEdge(const T & src, const T & dst);
|
||||
void dropEdge(const T & src, const T & dst);
|
||||
|
||||
// Returns the path from {from} to {to}
|
||||
std::deque<T> shortest_path(const T & from, const T & to);
|
||||
|
||||
private:
|
||||
struct Vertex {
|
||||
T data;
|
||||
|
||||
// It's a bit redundant to preserve both, but
|
||||
// it makes it possible to traverse both ways as
|
||||
// needed.
|
||||
std::unordered_set<I> parents;
|
||||
std::unordered_set<I> children;
|
||||
// it makes it possible with and against the
|
||||
// directions possible
|
||||
std::unordered_set<T> parents;
|
||||
std::unordered_set<T> children;
|
||||
};
|
||||
|
||||
std::unordered_map<I, Vertex> vertices;
|
||||
std::unordered_map<T, Vertex> vertices;
|
||||
std::unordered_set<T> roots;
|
||||
};
|
||||
|
||||
template<typename I, typename T>
|
||||
void DAG<I,T>::addVertex(I id, T && data) {
|
||||
vertices.emplace(id, Vertex{std::move(data), {}});
|
||||
}
|
||||
#include "DAG.impl"
|
||||
|
||||
template<typename I, typename T>
|
||||
void DAG<I,T>::addEdge(I from, I to) {
|
||||
auto src = vertices.find(from);
|
||||
if (src == vertices.end())
|
||||
throw std::runtime_error("Invalid from during edge insertion");
|
||||
auto dst = vertices.find(to);
|
||||
if (dst == vertices.end())
|
||||
throw std::runtime_error("Invalid dst during edge insertion");
|
||||
|
||||
// ensure that no cycles are introduced
|
||||
|
||||
|
||||
// Add the edge
|
||||
src->second.children.insert(to);
|
||||
dst->second.parents.insert(from);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,20 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("DAG Basic Tests", "[dag]") {
|
||||
daggy::DAG<int, std::string> dag;
|
||||
daggy::DAG<int> dag;
|
||||
|
||||
dag.addVertex(0, "hello");
|
||||
dag.addVertex(1, "goodbye");
|
||||
dag.addVertex(0);
|
||||
for (int i = 1; i < 10; ++i) {
|
||||
dag.addVertex(i);
|
||||
dag.addEdge(i-1, i);
|
||||
}
|
||||
|
||||
dag.addEdge(0, 1);
|
||||
dag.addEdge(5, 9);
|
||||
|
||||
auto sp = dag.shortest_path(1,9);
|
||||
std::cout << "Shortest path from 1 to 10: (";
|
||||
for (auto k : sp) {
|
||||
std::cout << k << " -> ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user