↰ Return to documentation for file (include/networkit/distance/STSP.hpp
)
/*
* STSP.hpp
*
* Created on: 15.06.2019
* Author: Eugenio Angriman <angrimae@hu-berlin.de>
*/
#ifndef NETWORKIT_DISTANCE_STSP_HPP_
#define NETWORKIT_DISTANCE_STSP_HPP_
#include <algorithm>
#include <ranges>
#include <unordered_map>
#include <vector>
#include <networkit/Globals.hpp>
#include <networkit/auxiliary/Log.hpp>
#include <networkit/base/Algorithm.hpp>
#include <networkit/graph/Graph.hpp>
namespace NetworKit {
class STSP : public Algorithm {
public:
STSP(const Graph &G, node source, node target, bool storePred = true)
: G(&G), source(source), target(target), storePred(storePred) {
if (!G.hasNode(source))
throw std::runtime_error("Error: source node not in the graph!");
if (!G.hasNode(target))
throw std::runtime_error("Error: target node not in the graph!");
if (source == target)
WARN("Source and target nodes are equal!");
}
template <class InputIt>
STSP(const Graph &G, node source, InputIt targetsFirst, InputIt targetsLast)
: G(&G), source(source), targets(targetsFirst, targetsLast), storePred(false) {
if (!G.hasNode(source))
throw std::runtime_error("Error: source node not in the graph!");
if (!std::all_of(targetsFirst, targetsLast, [&G](node u) { return G.hasNode(u); }))
throw std::runtime_error("Error: target node not in the graph!");
}
virtual std::vector<node> getPath() const {
checkStorePredecessors();
assureFinished();
return path;
}
const std::vector<node> &getPredecessors() const {
checkStorePredecessors();
assureFinished();
return pred;
}
edgeweight getDistance() const {
assureFinished();
return distance;
}
const std::vector<edgeweight> &getDistances() const {
assureFinished();
return distances;
}
void setSource(node newSource) {
assert(G->hasNode(newSource));
source = newSource;
}
void setTarget(node newTarget) {
assert(G->hasNode(newTarget));
target = newTarget;
targets.clear();
}
template <class InputIt>
void setTargets(InputIt targetsFirst, InputIt targetsLast) {
assert(std::all_of(targetsFirst, targetsLast, [&](auto u) { return G->hasNode(u); }));
targets.assign(targetsFirst, targetsLast);
}
const std::unordered_map<node, index> &getTargetIndexMap() const {
assureFinished();
return targetIdx;
}
protected:
const Graph *G;
node source = none, target = none;
std::vector<node> targets;
const bool storePred;
std::vector<node> pred, path;
edgeweight distance;
std::vector<edgeweight> distances;
std::unordered_map<node, index> targetIdx;
// Builds a source-target shortest path using the predecessors
void buildPath();
void checkStorePredecessors() const {
if (!storePred)
WARN("Predecessors not stored.");
}
void init() {
hasRun = false;
if (storePred)
pred.resize(G->upperNodeIdBound());
}
};
inline void STSP::buildPath() {
path.clear();
node t = target;
while (pred[t] != source) {
path.push_back(pred[t]);
t = pred[t];
}
std::ranges::reverse(path);
}
} // namespace NetworKit
#endif // NETWORKIT_DISTANCE_STSP_HPP_