Shortest path found
This commit is contained in:
@@ -1,56 +1,38 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace daggy {
|
namespace daggy {
|
||||||
|
template<typename T>
|
||||||
template<typename I, typename T>
|
|
||||||
class DAG {
|
class DAG {
|
||||||
public:
|
public:
|
||||||
DAG() {}
|
DAG() {}
|
||||||
|
|
||||||
void addVertex(I id, T && data);
|
void addVertex(T id);
|
||||||
void dropVertex(I id);
|
void dropVertex(const T & id);
|
||||||
void updateVertex(I id, T && data);
|
|
||||||
|
|
||||||
void addEdge(I src, I dst);
|
void addEdge(const T & src, const T & dst);
|
||||||
void dropEdge(I src, I 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:
|
private:
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
T data;
|
|
||||||
|
|
||||||
// It's a bit redundant to preserve both, but
|
// It's a bit redundant to preserve both, but
|
||||||
// it makes it possible to traverse both ways as
|
// it makes it possible with and against the
|
||||||
// needed.
|
// directions possible
|
||||||
std::unordered_set<I> parents;
|
std::unordered_set<T> parents;
|
||||||
std::unordered_set<I> children;
|
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>
|
#include "DAG.impl"
|
||||||
void DAG<I,T>::addVertex(I id, T && data) {
|
|
||||||
vertices.emplace(id, Vertex{std::move(data), {}});
|
|
||||||
}
|
|
||||||
|
|
||||||
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"
|
#include "catch.hpp"
|
||||||
|
|
||||||
TEST_CASE("DAG Basic Tests", "[dag]") {
|
TEST_CASE("DAG Basic Tests", "[dag]") {
|
||||||
daggy::DAG<int, std::string> dag;
|
daggy::DAG<int> dag;
|
||||||
|
|
||||||
dag.addVertex(0, "hello");
|
dag.addVertex(0);
|
||||||
dag.addVertex(1, "goodbye");
|
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