// // Created by max on 19.07.22. // #ifndef PDS_PDS_HPP #define PDS_PDS_HPP #include #include #include #include #include #include #include "map.hpp" #include "utility.hpp" #include #include #include namespace pds { enum class SolveState { Optimal, Timeout, Infeasible, Heuristic, Other }; struct SolveResult { size_t lower; size_t upper; SolveState state; }; SolveState combineSolveState(SolveState first, SolveState second); enum class PmuState : signed char { Blank = 0, Active = 1, Inactive = -1 }; struct Bus { std::string name; long id; bool zero_injection; PmuState pmu; }; #ifdef USE_HASHMAP using PowerGrid = mpgraphs::MapGraph; using ObservationGraph = mpgraphs::MapGraph; using VertexSet = mpgraphs::set; template using VertexMap = mpgraphs::map; #else using Timestamp = std::uint8_t; using PowerGrid = mpgraphs::VecGraph; using ObservationGraph = mpgraphs::VecGraph; using VertexSet = mpgraphs::VecSet; template using VertexMap = mpgraphs::VecMap; #endif using VertexList = std::vector; template size_t intersectionSize(const set& first, const set& second) { size_t count = 0; for (auto x: first) { if (second.contains(x)) { ++count; } } return count; } template bool isSuperset(const set &container, const set &other) { if (other.size() > container.size()) return false; for (auto x: other) { if (!container.contains(x)) return false; } return true; } class PdsState { public: using Vertex = PowerGrid::VertexDescriptor; private: VertexMap m_unobserved_degree; VertexSet m_seen; size_t m_numActive; size_t m_numInactive; PowerGrid m_graph; ObservationGraph m_dependencies; //mpgraphs::MapGraph m_dependencies; void propagate(std::vector& queue); bool observe(Vertex vertex, Vertex origin); bool observeOne(Vertex vertex, Vertex origin, std::vector& queue); inline bool disableLowDegreeRecursive( PowerGrid::VertexDescriptor start, VertexSet& seen ); public: PdsState(); explicit PdsState(PowerGrid&& graph); explicit PdsState(const PowerGrid& graph); PdsState(const PdsState&) = default; PdsState(PdsState&&) = default; PdsState& operator=(const PdsState&) = default; PdsState& operator=(PdsState&&) = default; void addEdge(Vertex source, Vertex target); void removeVertex(Vertex v); [[nodiscard]] inline bool isZeroInjection(Vertex vertex) const { return m_graph[vertex].zero_injection; } [[nodiscard]] inline PmuState activeState(Vertex vertex) const { return m_graph[vertex].pmu; } [[nodiscard]] inline bool isActive(Vertex vertex) const { return activeState(vertex) == PmuState::Active; } [[nodiscard]] inline bool isBlank(Vertex vertex) const { return activeState(vertex) == PmuState::Blank; } [[nodiscard]] inline bool isInactive(Vertex vertex) const { return activeState(vertex) == PmuState::Inactive; } [[nodiscard]] inline bool isObserved(Vertex vertex) const { return m_dependencies.hasVertex(vertex); } [[nodiscard]] inline bool isObservingEdge(Vertex source, Vertex target) const { return m_dependencies.hasEdge(source, target); } [[nodiscard]] inline size_t unobservedDegree(Vertex v) const { assert(m_unobserved_degree.at(v) == ranges::distance(m_graph.neighbors(v) | ranges::views::filter([this](auto v) { return !isObserved(v);}))); return m_unobserved_degree.at(v); } bool setActive(Vertex vertex); bool unsetActive(Vertex vertex); bool setInactive(Vertex vertex); bool setBlank(Vertex vertex); [[nodiscard]] inline bool allObserved() const { return numObserved() == graph().numVertices(); } [[nodiscard]] inline size_t numObserved() const { return m_dependencies.numVertices(); } [[nodiscard]] inline size_t numUnobserved() const { return graph().numVertices() - numObserved(); } [[nodiscard]] inline size_t numActive() const { assert(ranges::distance(graph().vertices() | ranges::views::filter([this](auto v) { return isActive(v); })) == (ssize_t)m_numActive); return m_numActive; } [[nodiscard]] inline size_t numInactive() const { assert(ranges::distance(graph().vertices() | ranges::views::filter([this](auto v) { return isInactive(v); })) == (ssize_t)m_numInactive); return m_numInactive; } [[nodiscard]] inline size_t numBlank() const { return graph().numVertices() - numActive() - numInactive(); } [[nodiscard]] inline size_t numZeroInjection() const { return ranges::distance(graph().vertices() | ranges::views::filter([this](auto v) { return isZeroInjection(v); })); } [[nodiscard]] inline const PowerGrid& graph() const { return m_graph; } [[nodiscard]] inline const auto& observationGraph() const { return m_dependencies; } inline PowerGrid && moveGraph() { return std::move(m_graph); } bool collapseLeaves(); bool disableLowDegree(); bool reduceObservedNonZi(); bool collapseDegreeTwo(); bool disableObservationNeighborhood(); bool activateNecessaryNodes(); bool collapseObservedEdges(); [[nodiscard]] std::vector subproblems() const; void applySubsolution(const PdsState& other); }; } // namespace pds #endif //PDS_PDS_HPP