Skip to content
Snippets Groups Projects
Commit 3a5ba7da authored by Jan Uhlík's avatar Jan Uhlík Committed by Jan Trávníček
Browse files

Add Jarkni-Prim algorithm.

parent 9e34d8b6
No related branches found
No related tags found
No related merge requests found
// JarnikPrim.cpp
//
// Created on: 19. 03. 2018
// Author: Jan Uhlik
// Modified by:
//
// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
#include "JarnikPrim.hpp"
#include <registration/AlgoRegistration.hpp>
namespace {
// ---------------------------------------------------------------------------------------------------------------------
// uni-directional
auto JarnikPrim1 = registration::AbstractRegister<spanning_tree::JarnikPrim,
graph::WeightedUndirectedGraph<>,
const graph::WeightedUndirectedGraph<> &,
const DefaultNodeType &>(spanning_tree::JarnikPrim::findSpanningTree);
}
// JarnikPrim.hpp
//
// Created on: 19. 03. 2018
// Author: Jan Uhlik
// Modified by:
//
// Copyright (c) 2017 Czech Technical University in Prague | Faculty of Information Technology. All rights reserved.
// Git repository: https://gitlab.fit.cvut.cz/algorithms-library-toolkit/automata-library
#ifndef ALIB2_JARNIKPRIM_HPP
#define ALIB2_JARNIKPRIM_HPP
#include <alib/pair>
#include <alib/set>
#include <alib/map>
#include <common/SupportFunction.hpp>
namespace spanning_tree {
class JarnikPrim {
// ---------------------------------------------------------------------------------------------------------------------
public:
template<typename TGraph, typename TNode>
static
TGraph
findSpanningTree(const TGraph &graph, const TNode &start);
// =====================================================================================================================
private:
template<typename TNode, typename TWeight>
struct Data {
ext::set<ext::pair<TWeight, TNode>> queue; // priority queue
ext::map<TNode, TWeight> g; // distances (aka G score)
ext::map<TNode, TNode> p; // parents
};
// ---------------------------------------------------------------------------------------------------------------------
template<typename TNode, typename TWeight>
inline static void init(JarnikPrim::Data<TNode, TWeight> &data, const TNode &start);
};
// =====================================================================================================================
template<typename TGraph, typename TNode>
TGraph JarnikPrim::findSpanningTree(const TGraph &graph, const TNode &start) {
using weight_type = typename TGraph::edge_type::weight_type;
TGraph res;
Data<TNode, weight_type> data;
// Init search
init(data, start);
while (!data.queue.empty()) {
TNode n = data.queue.begin()->second;
data.queue.erase(data.queue.begin());
// If not already in spanning tree add it
auto search = data.p.find(n);
if (search != data.p.end()) {
res.addEdge(search->second, n, data.g.at(n));
}
for (const auto &s_edge: graph.successorEdges(n)) {
const TNode &s = common::SupportFunction::other(s_edge, n); // successor
// Calculate new G score
weight_type gscore = s_edge.weight();
// Search if the node s was already visited
auto search_d = data.g.find(s);
// If not or the distance can be improve do relaxation
if (search_d == data.g.end() || search_d->second > gscore) {
// Search if the node s is in OPEN
auto search_q = data.queue.find(ext::make_pair(search_d->second, s));
if (search_q != data.queue.end()) {
// Erase node from priority queue
data.queue.erase(search_q);
}
data.g[s] = gscore;
data.p.insert_or_assign(s, n);
data.queue.insert(ext::make_pair(data.g[s], s));
}
}
}
return res;
}
// ---------------------------------------------------------------------------------------------------------------------
template<typename TNode, typename TWeight>
void JarnikPrim::init(JarnikPrim::Data<TNode, TWeight> &data, const TNode &start) {
data.g[start] = 0;
data.p.insert_or_assign(start, start);
data.queue.insert(ext::make_pair(data.g[start], start));
}
// ---------------------------------------------------------------------------------------------------------------------
} // namespace spanning_tree
#endif //ALIB2_JARNIKPRIM_HPP
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment