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