diff --git a/include/aoc/LanParty.hpp b/include/aoc/LanParty.hpp index 9819a79..94ac1ab 100644 --- a/include/aoc/LanParty.hpp +++ b/include/aoc/LanParty.hpp @@ -15,7 +15,7 @@ #pragma once -#include +#include #include class LanParty @@ -27,9 +27,10 @@ class LanParty virtual void processDataLine(const std::string& line) override; virtual void finish() override; private: - Graph lan_; - void computeInterconnectedThreeSetCount(const Vertex& vertexTx); - bool shallProcessVertex(const Vertex& vertexToCheck, const Vertex& vertexTx) const; - const std::string getFirstTxComputerName() const; - const std::string getLastTxComputerName() const; + static constexpr std::string getFirstTxComputerName(); + static constexpr std::string getLastTxComputerName(); + LabelGraph lan_; + int findOrAddVertex(const std::string& vertexId); + void computeInterconnectedThreeSetCount(const int vertexTx); + bool canProcessVertex(const int vertexToCheck, const int vertexTx) const; }; diff --git a/include/aoc/RamRun.hpp b/include/aoc/RamRun.hpp index 80df240..2817109 100644 --- a/include/aoc/RamRun.hpp +++ b/include/aoc/RamRun.hpp @@ -15,8 +15,9 @@ #pragma once +#include #include -#include +#include #include class RamRun @@ -33,11 +34,11 @@ class RamRun int maxBytes_; int nBytes_; Grid vertexReferences_; - WeightedEdgeGraph::PathsResult dijkstraResult_; + GraphPathsResult dijkstraResult_; static constexpr char getUnknownVertexReference(); static constexpr char getNoVertexReference(); bool tryMarkCorrupted(const std::string& line, int& corruptedVertex); - WeightedEdgeGraph buildGraph(); - int getVertex(WeightedEdgeGraph& graph, const size_t x, const size_t y); + WeightGraph buildGraph(); + int getVertex(WeightGraph& graph, const size_t x, const size_t y); void resetVertexReferences(); }; diff --git a/include/aoc/ReindeerMaze.hpp b/include/aoc/ReindeerMaze.hpp index 2340d12..3d0d648 100644 --- a/include/aoc/ReindeerMaze.hpp +++ b/include/aoc/ReindeerMaze.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -39,15 +39,15 @@ class ReindeerMaze static constexpr char getEndChar(); static constexpr char getWallChar(); static constexpr int getTurnCost(); - void buildPathSegmentGraph(WeightedEdgeGraph& graph, VertexAttachedPositions& vertexAttachedPositions, + void buildPathSegmentGraph(WeightGraph& graph, VertexAttachedPositions& vertexAttachedPositions, const int entry, const int exit); void initializeWorkList(std::list& crossings, const int entryVertex); void addCheckedIncidence(std::vector& incidences, const Point2 start, const Point2 direction); - void addPathSegmentEdges(WeightedEdgeGraph& graph, const ReindeerMazePathIncidence& pathIncidence, + void addPathSegmentEdges(WeightGraph& graph, const ReindeerMazePathIncidence& pathIncidence, const std::vector& otherPathIncidences); std::pair makePositionsIdPair(const Point2& position1, const Point2& position2); - int calcShortestPaths(const WeightedEdgeGraph& graph, const VertexAttachedPositions& vertexAttachedPositions, + int calcShortestPaths(const WeightGraph& graph, const VertexAttachedPositions& vertexAttachedPositions, const int entry, const int exit, const std::vector& shortestDistances); int getNUniqueAttachedPositions(const VertexAttachedPositions& vertexAttachedPositions, const std::set& vertices); diff --git a/include/aoc/common/Graph.hpp b/include/aoc/common/Graph.hpp index f3f8318..96df9a0 100644 --- a/include/aoc/common/Graph.hpp +++ b/include/aoc/common/Graph.hpp @@ -1,5 +1,5 @@ // Solutions to the Advent Of Code 2024. -// Copyright (C) 2024 Stefan Müller +// Copyright (C) 2025 Stefan Müller // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software @@ -15,18 +15,95 @@ #pragma once -#include -#include +#include #include -#include - class Graph { public: - const std::map>& getVertices() const; - void addEdge(const std::string& vertexId1, const std::string& vertexId2); + int addVertex(); + void addEdge(const int vertex1, const int vertex2); + size_t getNVertices() const; + size_t getNEdges() const; + bool areAdjacent(const int vertex1, const int vertex2) const; + + struct Incidence + { + public: + Incidence(const int vertex, const int edge) + : vertex{ vertex }, edge{ edge } + { + } + int vertex; + int edge; + }; + + struct NeighborIterator + { + public: + // Iterator traits. + using difference_type = std::ptrdiff_t; + using value_type = Incidence; + using pointer = const value_type*; + using reference = const value_type&; + using iterator_category = std::forward_iterator_tag; + + NeighborIterator(const Graph& graph, const int vertex) + : graph_{ graph }, incidence_{ -1 }, value_{ -1, -1 } + { + if (vertex >= 0 && vertex < graph_.firstVertexIncidences_.size()) + { + setIncidence(graph_.firstVertexIncidences_[vertex]); + } + }; + NeighborIterator& operator++() + { + if (incidence_ >= 0) + { + setIncidence(graph_.nextIncidences_[incidence_]); + } + return *this; + } + NeighborIterator operator++(int) + { + NeighborIterator it = *this; + ++(*this); + return it; + } + bool operator==(NeighborIterator other) const + { + return incidence_ == other.incidence_; + } + bool operator!=(NeighborIterator other) const + { + return !(*this == other); + } + const reference operator*() const + { + return value_; + } + const pointer operator->() const + { + return &value_; + } + private: + const Graph& graph_; + int incidence_; + value_type value_; + void setIncidence(const int incidence) + { + incidence_ = incidence; + if (incidence_ >= 0) + { + value_ = { graph_.incidenceVertices_[incidence_], incidence_ >> 1 }; + } + } + }; + + NeighborIterator begin(const int vertex) const; + NeighborIterator end() const; private: - std::map> vertices_; - std::shared_ptr findOrAddVertex(const std::string& vertexId); + std::vector firstVertexIncidences_{}; + std::vector nextIncidences_{}; + std::vector incidenceVertices_{}; }; diff --git a/include/aoc/common/VertexEdgeIncidence.hpp b/include/aoc/common/GraphPathsResult.hpp similarity index 67% rename from include/aoc/common/VertexEdgeIncidence.hpp rename to include/aoc/common/GraphPathsResult.hpp index 452c061..75af80d 100644 --- a/include/aoc/common/VertexEdgeIncidence.hpp +++ b/include/aoc/common/GraphPathsResult.hpp @@ -15,14 +15,19 @@ #pragma once -class VertexEdgeIncidence +#include + +class GraphPathsResult { public: - VertexEdgeIncidence(const int vertex, const int next) + GraphPathsResult() + : distances{}, predecessors{} { - this->vertex = vertex; - this->next = next; } - int vertex; - int next; + GraphPathsResult(const size_t size, const int initialDistance, const int initialPredecessor) + : distances(size, initialDistance), predecessors(size, initialPredecessor) + { + } + std::vector distances; + std::vector predecessors; }; diff --git a/include/aoc/common/LabelGraph.hpp b/include/aoc/common/LabelGraph.hpp new file mode 100644 index 0000000..493b106 --- /dev/null +++ b/include/aoc/common/LabelGraph.hpp @@ -0,0 +1,38 @@ +// Solutions to the Advent Of Code 2024. +// Copyright (C) 2025 Stefan Müller +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +#pragma once + +#include +#include +#include + +#include + +class LabelGraph +{ +public: + int addVertex(const std::string& label); + void addEdge(const int vertex1, const int vertex2); + bool areAdjacent(const int vertex1, const int vertex2) const; + const std::string& getVertexLabel(const int vertex) const; + const std::map& getLabelVertices() const; + Graph::NeighborIterator begin(const int vertex) const; + Graph::NeighborIterator end() const; +private: + Graph graph_{}; + std::vector vertexLabels_{}; + std::map labelVertices_{}; +}; diff --git a/include/aoc/common/WeightGraph.hpp b/include/aoc/common/WeightGraph.hpp new file mode 100644 index 0000000..e0acd0d --- /dev/null +++ b/include/aoc/common/WeightGraph.hpp @@ -0,0 +1,38 @@ +// Solutions to the Advent Of Code 2024. +// Copyright (C) 2025 Stefan Müller +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +#pragma once + +#include + +#include +#include + +class WeightGraph +{ +public: + static constexpr int getInfiniteDistance(); + int addVertex(const int weight); + void addEdge(const int vertex1, const int vertex2, const int weight); + int getVertexWeight(const int vertex) const; + int getEdgeWeight(const int edge) const; + GraphPathsResult dijkstra(const int source) const; + Graph::NeighborIterator begin(const int vertex) const; + Graph::NeighborIterator end() const; +private: + Graph graph_{}; + std::vector edgeWeights_{}; + std::vector vertexWeights_{}; +}; diff --git a/include/aoc/common/WeightedEdgeGraph.hpp b/include/aoc/common/WeightedEdgeGraph.hpp deleted file mode 100644 index d998fa9..0000000 --- a/include/aoc/common/WeightedEdgeGraph.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// Solutions to the Advent Of Code 2024. -// Copyright (C) 2025 Stefan Müller -// -// This program is free software: you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free Software -// Foundation, either version 3 of the License, or (at your option) any later -// version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License along with -// this program. If not, see . - -#pragma once - -#include -#include - -#include - -class WeightedEdgeGraph -{ -public: - WeightedEdgeGraph(); - int addVertex(const int weight = 0); - void addEdge(const int vertex1, const int vertex2, const int weight); - int getVertexWeight(const int vertex) const; - int getEdgeWeight(const int edge) const; - - struct PathsResult - { - PathsResult() - : distances{}, predecessors{} - { - } - PathsResult(const size_t size, const int initialDistance, const int initialPredecessor) - : distances(size, initialDistance), predecessors(size, initialPredecessor) - { - } - std::vector distances; - std::vector predecessors; - }; - - PathsResult dijkstra(const int source) const; - static constexpr int getInfiniteDistance(); - - struct Incidence - { - public: - Incidence(const int vertex, const int edge) - : vertex{ vertex }, edge{ edge } - { - } - int vertex; - int edge; - }; - - struct NeighborIterator - { - public: - // Iterator traits. - using difference_type = std::ptrdiff_t; - using value_type = Incidence; - using pointer = const value_type*; - using reference = const value_type&; - using iterator_category = std::forward_iterator_tag; - - NeighborIterator(const WeightedEdgeGraph& graph, const int vertex) - : graph_{ graph }, incidence_{ -1 }, value_{ -1, -1 } - { - if (vertex >= 0 && vertex < graph_.firstVertexIncidences_.size()) - { - setIncidence(graph_.firstVertexIncidences_[vertex]); - } - }; - NeighborIterator& operator++() - { - if (incidence_ >= 0) - { - setIncidence(graph_.vertexEdgeIncidences_[incidence_].next); - } - return *this; - } - NeighborIterator operator++(int) - { - NeighborIterator it = *this; - ++(*this); - return it; - } - bool operator==(NeighborIterator other) const - { - return incidence_ == other.incidence_; - } - bool operator!=(NeighborIterator other) const - { - return !(*this == other); - } - const reference operator*() const - { - return value_; - } - const pointer operator->() const - { - return &value_; - } - private: - const WeightedEdgeGraph& graph_; - int incidence_; - value_type value_; - void setIncidence(const int incidence) - { - incidence_ = incidence; - if (incidence_ >= 0) - { - value_ = { graph_.vertexEdgeIncidences_[incidence_].vertex, incidence_ >> 1 }; - } - } - }; - - NeighborIterator begin(const int vertex) const; - NeighborIterator end() const; -private: - std::vector firstVertexIncidences_; - std::vector vertexEdgeIncidences_; - std::vector edgeWeights_; - std::vector vertexWeights_; -}; diff --git a/src/LanParty.cpp b/src/LanParty.cpp index d0c6210..fcb1034 100644 --- a/src/LanParty.cpp +++ b/src/LanParty.cpp @@ -27,58 +27,72 @@ const int LanParty::getPuzzleDay() const void LanParty::processDataLine(const std::string& line) { - lan_.addEdge(line.substr(0, 2), line.substr(3, 2)); + lan_.addEdge(findOrAddVertex(line.substr(0, 2)), findOrAddVertex(line.substr(3, 2))); } void LanParty::finish() { - auto vertices = lan_.getVertices(); - // This works as long as "ta" is present as a computername, otherwise we would have to use vertices.find_if(). - auto iterTx = vertices.find(getFirstTxComputerName()); - while (iterTx != vertices.end() && iterTx->second->getId() <= getLastTxComputerName()) + const auto& vertices = lan_.getLabelVertices(); + auto itTx = vertices.lower_bound(getFirstTxComputerName()); + const auto itTxEnd = vertices.upper_bound(getLastTxComputerName()); + while (itTx != itTxEnd) { - computeInterconnectedThreeSetCount(*iterTx->second); - iterTx++; + computeInterconnectedThreeSetCount(itTx->second); + itTx++; } } -void LanParty::computeInterconnectedThreeSetCount(const Vertex& vertexTx) -{ - auto neighborsOfTx = vertexTx.getNeighbors(); - for (size_t i = 0; i < neighborsOfTx.size(); i++) - { - auto vertexA = neighborsOfTx[i].lock(); - if (shallProcessVertex(*vertexA, vertexTx)) - { - for (size_t j{ i + 1 }; j < neighborsOfTx.size(); j++) - { - auto vertexB = neighborsOfTx[j].lock(); - if (shallProcessVertex(*vertexB, vertexTx)) - { - for (auto& neighborOfA : vertexA->getNeighbors()) - { - if (vertexB == neighborOfA.lock()) - { - part1++; - } - } - } - } - } - } -} - -bool LanParty::shallProcessVertex(const Vertex& vertexToCheck, const Vertex& vertexTx) const -{ - return (vertexToCheck.getId()[0] != 't' || vertexToCheck.getId() > vertexTx.getId()); -} - -const std::string LanParty::getFirstTxComputerName() const +constexpr std::string LanParty::getFirstTxComputerName() { return "ta"; } -const std::string LanParty::getLastTxComputerName() const +constexpr std::string LanParty::getLastTxComputerName() { return "tz"; } + +int LanParty::findOrAddVertex(const std::string& vertexId) +{ + const auto& vertices = lan_.getLabelVertices(); + const auto found = vertices.find(vertexId); + if (found != vertices.end()) + { + return found->second; + } + else + { + return lan_.addVertex(vertexId); + } +} + +void LanParty::computeInterconnectedThreeSetCount(const int vertexTx) +{ + auto itFirstNeighbor = lan_.begin(vertexTx); + while (itFirstNeighbor != lan_.end()) + { + if (canProcessVertex(itFirstNeighbor->vertex, vertexTx)) + { + auto itSecondNeighbor = itFirstNeighbor; + itSecondNeighbor++; + while (itSecondNeighbor != lan_.end()) + { + if (canProcessVertex(itSecondNeighbor->vertex, vertexTx)) + { + if (lan_.areAdjacent(itFirstNeighbor->vertex, itSecondNeighbor->vertex)) + { + part1++; + } + } + itSecondNeighbor++; + } + } + itFirstNeighbor++; + } +} + +bool LanParty::canProcessVertex(const int vertexToCheck, const int vertexTx) const +{ + const std::string& label{ lan_.getVertexLabel(vertexToCheck) }; + return (label[0] != 't' || label > lan_.getVertexLabel(vertexTx)); +} diff --git a/src/RamRun.cpp b/src/RamRun.cpp index 84b2b83..87aa50a 100644 --- a/src/RamRun.cpp +++ b/src/RamRun.cpp @@ -65,7 +65,7 @@ void RamRun::processDataLine(const std::string& line) auto graph = buildGraph(); dijkstraResult_ = graph.dijkstra(vertexReferences_[0][0]); if (dijkstraResult_.distances[vertexReferences_[memorySize_ - 1][memorySize_ - 1]] - == WeightedEdgeGraph::getInfiniteDistance()) + == WeightGraph::getInfiniteDistance()) { // Path is blocked. part2 = line; @@ -105,9 +105,9 @@ bool RamRun::tryMarkCorrupted(const std::string& line, int& corruptedVertex) return false; } -WeightedEdgeGraph RamRun::buildGraph() +WeightGraph RamRun::buildGraph() { - WeightedEdgeGraph graph; + WeightGraph graph; for (size_t j = 0; j < vertexReferences_.getNRows(); j++) { for (size_t i = 0; i < vertexReferences_.getNColumns(); i++) @@ -132,15 +132,14 @@ WeightedEdgeGraph RamRun::buildGraph() } } } - return graph; } -int RamRun::getVertex(WeightedEdgeGraph& graph, const size_t x, const size_t y) +int RamRun::getVertex(WeightGraph& graph, const size_t x, const size_t y) { if (vertexReferences_[y][x] == getUnknownVertexReference()) { - vertexReferences_[y][x] = graph.addVertex(); + vertexReferences_[y][x] = graph.addVertex(0); } return vertexReferences_[y][x]; } diff --git a/src/ReindeerMaze.cpp b/src/ReindeerMaze.cpp index 1b4c7b9..9b5c6fe 100644 --- a/src/ReindeerMaze.cpp +++ b/src/ReindeerMaze.cpp @@ -40,7 +40,7 @@ void ReindeerMaze::finish() // do not want to hardcode this. VertexAttachedPositions vertexAttachedPositions; - WeightedEdgeGraph graph{}; + WeightGraph graph{}; auto entry = graph.addVertex(0); auto exit = graph.addVertex(0); buildPathSegmentGraph(graph, vertexAttachedPositions, entry, exit); @@ -72,7 +72,7 @@ constexpr int ReindeerMaze::getTurnCost() // Constructs the graph of path segment incidences, starting with a graph that already contains the entry and the exit // vertices. -void ReindeerMaze::buildPathSegmentGraph(WeightedEdgeGraph& graph, VertexAttachedPositions& vertexAttachedPositions, +void ReindeerMaze::buildPathSegmentGraph(WeightGraph& graph, VertexAttachedPositions& vertexAttachedPositions, const int entry, const int exit) { // Uses list for work items to prevent invalidation of iterators on add. @@ -243,7 +243,7 @@ void ReindeerMaze::addCheckedIncidence(std::vector& i } } -void ReindeerMaze::addPathSegmentEdges(WeightedEdgeGraph& graph, const ReindeerMazePathIncidence& pathIncidence, +void ReindeerMaze::addPathSegmentEdges(WeightGraph& graph, const ReindeerMazePathIncidence& pathIncidence, const std::vector& otherPathIncidences) { for (auto& otherIncidence : otherPathIncidences) @@ -267,13 +267,13 @@ std::pair ReindeerMaze::makePositionsIdPair(const Point2& position1, c return std::make_pair(position1.x * offset + position1.y, position2.x * offset + position2.y); } -int ReindeerMaze::calcShortestPaths(const WeightedEdgeGraph& graph, +int ReindeerMaze::calcShortestPaths(const WeightGraph& graph, const VertexAttachedPositions& vertexAttachedPositions, const int entry, const int exit, const std::vector& shortestDistances) { std::set shortestPathsVertices{}; - std::stack stack{}; + std::stack stack{}; auto v = graph.begin(entry); stack.emplace(v); int cost{ 0 }; diff --git a/src/common/Graph.cpp b/src/common/Graph.cpp index e4de588..bb380eb 100644 --- a/src/common/Graph.cpp +++ b/src/common/Graph.cpp @@ -1,5 +1,5 @@ // Solutions to the Advent Of Code 2024. -// Copyright (C) 2024 Stefan Müller +// Copyright (C) 2025 Stefan Müller // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free Software @@ -15,32 +15,53 @@ #include -#include - -const std::map>& Graph::getVertices() const +int Graph::addVertex() { - return vertices_; + firstVertexIncidences_.push_back(-1); + return static_cast(firstVertexIncidences_.size()) - 1; } -void Graph::addEdge(const std::string& vertexId1, const std::string& vertexId2) +void Graph::addEdge(const int vertex1, const int vertex2) { - auto v1 = findOrAddVertex(vertexId1); - auto v2 = findOrAddVertex(vertexId2); - v1->addNeighbor(v2); - v2->addNeighbor(v1); + incidenceVertices_.push_back(vertex2); + nextIncidences_.push_back(firstVertexIncidences_[vertex1]); + firstVertexIncidences_[vertex1] = static_cast(incidenceVertices_.size()) - 1; + + incidenceVertices_.push_back(vertex1); + nextIncidences_.push_back(firstVertexIncidences_[vertex2]); + firstVertexIncidences_[vertex2] = static_cast(incidenceVertices_.size()) - 1; } -std::shared_ptr Graph::findOrAddVertex(const std::string& vertexId) +size_t Graph::getNVertices() const { - auto iter = vertices_.find(vertexId); - if (iter != vertices_.end()) + return firstVertexIncidences_.size(); +} + +size_t Graph::getNEdges() const +{ + return nextIncidences_.size() >> 1; +} + +bool Graph::areAdjacent(const int vertex1, const int vertex2) const +{ + auto it = begin(vertex1); + while (it != end()) { - return (*iter).second; - } - else - { - auto v = std::make_shared(vertexId); - vertices_.insert({ vertexId, v }); - return v; + if (it->vertex == vertex2) + { + return true; + } + it++; } + return false; +} + +Graph::NeighborIterator Graph::begin(const int vertex) const +{ + return { *this, vertex }; +} + +Graph::NeighborIterator Graph::end() const +{ + return { *this, -1 }; } diff --git a/src/common/LabelGraph.cpp b/src/common/LabelGraph.cpp new file mode 100644 index 0000000..4bbc742 --- /dev/null +++ b/src/common/LabelGraph.cpp @@ -0,0 +1,53 @@ +// Solutions to the Advent Of Code 2024. +// Copyright (C) 2025 Stefan Müller +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation, either version 3 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +#include + +int LabelGraph::addVertex(const std::string& label) +{ + vertexLabels_.push_back(label); + labelVertices_.insert({ label, static_cast(vertexLabels_.size()) - 1 }); + return graph_.addVertex(); +} + +void LabelGraph::addEdge(const int vertex1, const int vertex2) +{ + graph_.addEdge(vertex1, vertex2); +} + +bool LabelGraph::areAdjacent(const int vertex1, const int vertex2) const +{ + return graph_.areAdjacent(vertex1, vertex2); +} + +const std::string& LabelGraph::getVertexLabel(const int vertex) const +{ + return vertexLabels_[vertex]; +} + +const std::map& LabelGraph::getLabelVertices() const +{ + return labelVertices_; +} + +Graph::NeighborIterator LabelGraph::begin(const int vertex) const +{ + return graph_.begin(vertex); +} + +Graph::NeighborIterator LabelGraph::end() const +{ + return graph_.end(); +} diff --git a/src/common/WeightedEdgeGraph.cpp b/src/common/WeightGraph.cpp similarity index 58% rename from src/common/WeightedEdgeGraph.cpp rename to src/common/WeightGraph.cpp index 8230775..5316204 100644 --- a/src/common/WeightedEdgeGraph.cpp +++ b/src/common/WeightGraph.cpp @@ -13,45 +13,41 @@ // You should have received a copy of the GNU General Public License along with // this program. If not, see . -#include +#include #include #include -WeightedEdgeGraph::WeightedEdgeGraph() - : firstVertexIncidences_{}, vertexEdgeIncidences_{}, edgeWeights_{} +constexpr int WeightGraph::getInfiniteDistance() { + return std::numeric_limits::max(); } -int WeightedEdgeGraph::addVertex(const int weight) +int WeightGraph::addVertex(const int weight) { - firstVertexIncidences_.push_back(-1); vertexWeights_.push_back(weight); - return (int)firstVertexIncidences_.size() - 1; + return graph_.addVertex(); } -void WeightedEdgeGraph::addEdge(const int vertex1, const int vertex2, const int weight) +void WeightGraph::addEdge(const int vertex1, const int vertex2, const int weight) { - vertexEdgeIncidences_.emplace_back(vertex2, firstVertexIncidences_[vertex1]); - firstVertexIncidences_[vertex1] = (int)vertexEdgeIncidences_.size() - 1; - vertexEdgeIncidences_.emplace_back(vertex1, firstVertexIncidences_[vertex2]); - firstVertexIncidences_[vertex2] = (int)vertexEdgeIncidences_.size() - 1; edgeWeights_.push_back(weight); + graph_.addEdge(vertex1, vertex2); } -int WeightedEdgeGraph::getVertexWeight(const int vertex) const +int WeightGraph::getVertexWeight(const int vertex) const { return vertexWeights_[vertex]; } -int WeightedEdgeGraph::getEdgeWeight(const int edge) const +int WeightGraph::getEdgeWeight(const int edge) const { return edgeWeights_[edge]; } -WeightedEdgeGraph::PathsResult WeightedEdgeGraph::dijkstra(const int source) const +GraphPathsResult WeightGraph::dijkstra(const int source) const { - PathsResult result(firstVertexIncidences_.size(), getInfiniteDistance(), -1); + GraphPathsResult result(graph_.getNVertices(), getInfiniteDistance(), -1); auto compare = [&result](int left, int right) { return result.distances[left] > result.distances[right]; }; std::priority_queue, decltype(compare)> queue{ compare }; @@ -78,17 +74,12 @@ WeightedEdgeGraph::PathsResult WeightedEdgeGraph::dijkstra(const int source) con return result; } -constexpr int WeightedEdgeGraph::getInfiniteDistance() +Graph::NeighborIterator WeightGraph::begin(const int vertex) const { - return std::numeric_limits::max(); + return graph_.begin(vertex); } -WeightedEdgeGraph::NeighborIterator WeightedEdgeGraph::begin(const int vertex) const +Graph::NeighborIterator WeightGraph::end() const { - return { *this, vertex }; -} - -WeightedEdgeGraph::NeighborIterator WeightedEdgeGraph::end() const -{ - return { *this, -1 }; + return graph_.end(); }