From ae146946748a8e0b9a96e6e21bd0842f572f76a3 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Wed, 17 May 2017 15:39:44 +0200 Subject: [PATCH] add Backbone length computation from dfa --- .../stringology/properties/BackboneLength.cpp | 22 ++++++ .../stringology/properties/BackboneLength.h | 75 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 alib2algo/src/stringology/properties/BackboneLength.cpp create mode 100644 alib2algo/src/stringology/properties/BackboneLength.h diff --git a/alib2algo/src/stringology/properties/BackboneLength.cpp b/alib2algo/src/stringology/properties/BackboneLength.cpp new file mode 100644 index 0000000000..f1f9f2d3de --- /dev/null +++ b/alib2algo/src/stringology/properties/BackboneLength.cpp @@ -0,0 +1,22 @@ +/* + * BackboneLength.cpp + * + * Created on: 17. 5. 2017 + * Author: Jan Travnicek + */ + +#include "BackboneLength.h" + +namespace stringology { + +namespace properties { + +unsigned BackboneLength::length ( const automaton::Automaton & automaton ) { + return dispatch ( automaton.getData ( ) ); +} + +auto backboneLengthDFA = BackboneLength::RegistratorWrapper < unsigned, automaton::DFA < > > ( BackboneLength::length ); + +} /* namespace properties */ + +} /* namespace stringology */ diff --git a/alib2algo/src/stringology/properties/BackboneLength.h b/alib2algo/src/stringology/properties/BackboneLength.h new file mode 100644 index 0000000000..d11b0cdb31 --- /dev/null +++ b/alib2algo/src/stringology/properties/BackboneLength.h @@ -0,0 +1,75 @@ +/* + * BackboneLength.h + * + * Created on: 17. 5. 2017 + * Author: Jan Travnicek + */ + +#ifndef BACKBONE_LENGTH_H +#define BACKBONE_LENGTH_H + +#include <automaton/Automaton.h> +#include <automaton/FSM/DFA.h> +#include <core/multipleDispatch.hpp> +#include <set> +#include <queue> +#include <algorithm> +#include <utility> + +namespace stringology { + +namespace properties { + +class BackboneLength : public std::SingleDispatch < BackboneLength, unsigned, const automaton::AutomatonBase & > { +public: + /** + * Computes length of backbone for a suffix/factor/oracle automaton + * @param automaton the suffix/factor/oracle automaton + * @return backbone length + */ + static unsigned length ( const automaton::Automaton & automaton ); + + template < class SymbolType, class StateType > + static unsigned length ( const automaton::DFA < SymbolType, StateType > & automaton ); + + template < class StateType > + class BackboneLengthLess { + public: + bool operator ( ) ( const std::pair < StateType, unsigned > & first, const std::pair < StateType, unsigned > & second ) { + return first.second < second.second; + } + }; + +}; + +template < class SymbolType, class StateType > +unsigned BackboneLength::length ( const automaton::DFA < SymbolType, StateType > & automaton ) { + std::priority_queue < std::pair < StateType, unsigned >, std::vector < std::pair < StateType, unsigned > >, BackboneLengthLess < StateType > > open; + std::map < StateType, unsigned > closed; + + unsigned max = 0; + open.push ( std::make_pair ( automaton.getInitialState ( ), max ) ); + + while ( ! open.empty ( ) ) { + std::pair < StateType, unsigned > current = std::move ( open.top ( ) ); + open.pop ( ); + unsigned & dist = closed [ current.first ]; + + if ( dist > current.second ) + continue; + + dist = current.second; + max = std::max ( max, current.second ); + + for ( const std::pair < const std::pair < StateType, SymbolType >, StateType > & target : automaton.getTransitionsFromState ( current.first ) ) + open.push ( std::make_pair ( target.second, current.second + 1 ) ); + } + + return max; +} + +} /* namespace properties */ + +} /* namespace stringology */ + +#endif /* BACKBONE_LENGTH_H */ -- GitLab