From c41214cc037b373da7ebcc1214d1f61ebcc4118c Mon Sep 17 00:00:00 2001 From: Tomas Pecka <tomas.pecka@fit.cvut.cz> Date: Thu, 10 Oct 2019 16:21:28 +0200 Subject: [PATCH] Tree Border Array - quadratic time solution --- alib2algo/src/tree/properties/BorderArray.cpp | 18 ++++ alib2algo/src/tree/properties/BorderArray.h | 83 +++++++++++++++++++ .../test-src/tests/borderArrayTest.cpp | 54 ++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 alib2algo/src/tree/properties/BorderArray.cpp create mode 100644 alib2algo/src/tree/properties/BorderArray.h create mode 100644 alib2integrationtest/test-src/tests/borderArrayTest.cpp diff --git a/alib2algo/src/tree/properties/BorderArray.cpp b/alib2algo/src/tree/properties/BorderArray.cpp new file mode 100644 index 0000000000..7ac7f17c54 --- /dev/null +++ b/alib2algo/src/tree/properties/BorderArray.cpp @@ -0,0 +1,18 @@ +/* + * BorderArray.cpp + * + * Created on: 4. 10. 2019 + * Author: Tomas Pecka, Jan Travnicek + */ + +#include "BorderArray.h" +#include <registration/AlgoRegistration.hpp> + +namespace { + +auto BorderArrayPrefixRankedBarNonlinearPattern = registration::AbstractRegister < tree::properties::BorderArray, ext::vector < size_t >, const tree::PrefixRankedBarNonlinearPattern < > & > ( tree::properties::BorderArray::construct ); +auto BorderArrayPrefixRankedBarPattern = registration::AbstractRegister < tree::properties::BorderArray, ext::vector < size_t >, const tree::PrefixRankedBarPattern < > & > ( tree::properties::BorderArray::construct ); +auto BorderArrayPrefixRankedNonlinearPattern = registration::AbstractRegister < tree::properties::BorderArray, ext::vector < size_t >, const tree::PrefixRankedNonlinearPattern < > & > ( tree::properties::BorderArray::construct ); +auto BorderArrayPrefixRankedPattern = registration::AbstractRegister < tree::properties::BorderArray, ext::vector < size_t >, const tree::PrefixRankedPattern < > & > ( tree::properties::BorderArray::construct ); + +} /* namespace */ diff --git a/alib2algo/src/tree/properties/BorderArray.h b/alib2algo/src/tree/properties/BorderArray.h new file mode 100644 index 0000000000..35cc993ddc --- /dev/null +++ b/alib2algo/src/tree/properties/BorderArray.h @@ -0,0 +1,83 @@ +/* + * BorderArray.cpp + * + * Created on: 4. 10. 2019 + * Author: Tomas Pecka, Jan Travnicek + */ + +#ifndef _ARBOLOGY_BORDER_ARRAY_H_ +#define _ARBOLOGY_BORDER_ARRAY_H_ + +#include <cstdlib> + +#include <alib/vector> + +#include <global/GlobalData.h> + +#include "SubtreeJumpTable.h" + +#include <tree/ranked/PrefixRankedBarNonlinearPattern.h> +#include <tree/ranked/PrefixRankedBarPattern.h> +#include <tree/ranked/PrefixRankedNonlinearPattern.h> +#include <tree/ranked/PrefixRankedPattern.h> + +namespace tree::properties { + +class BorderArray { + +public: + template < class PrefixRankedPatternType > + static ext::vector < size_t > construct ( const PrefixRankedPatternType & pattern ); +}; + +template < class PrefixRankedPatternType > +ext::vector < size_t > BorderArray::construct ( const PrefixRankedPatternType & pattern ) { + ext::vector < int > subtreeJumpTable = SubtreeJumpTable::compute ( pattern ); + ext::vector < size_t > res ( pattern.getContent ( ).size ( ) + 1, 0 ); + ext::vector < unsigned > mins ( pattern.getContent ( ).size ( ) + 1 ); + for ( unsigned i = 0; i <= pattern.getContent ( ) .size ( ); i++ ) + mins [ i ] = i + 1; + res [ 0 ] = -1; + + for ( unsigned ofs = 1; ofs < pattern.getContent ( ).size ( ); ofs++ ) { + + unsigned i = 0; // index do patternu + unsigned j = ofs; // index do factoru + + while ( 1 ) { + if ( i >= pattern.getContent ( ).size ( ) ) { + while ( j < pattern.getContent ( ).size ( ) ) { + mins [ j ] = std::min ( mins [ j ], ofs ); + j++; + } + break; + } else if ( j >= pattern.getContent ( ).size ( ) ) { + break; + } else if ( pattern.getContent ( )[ i ] == pattern.getContent ( )[ j ] ) { + mins [ j ] = std::min ( mins [ j ], ofs );; + i++; + j++; + } else if ( pattern.getContent ( )[ i ] == pattern.getSubtreeWildcard ( ) || pattern.getContent ( )[ j ] == pattern.getSubtreeWildcard ( ) ) { + for ( int k = ( int ) j; k < subtreeJumpTable [ j ] ; k++ ) + mins [ k ] = std::min ( mins [ k ], ofs );; + + i = subtreeJumpTable[ i ]; + j = subtreeJumpTable[ j ]; + } else { + break; + } + } + } + + // std::cout << mins << std::endl; + + for ( size_t i = 1; i <= pattern.getContent ( ).size ( ); i++ ) { + res [ i ] = i - mins [ i - 1 ]; + } + + return res; +} + +} /* namespace tree::properties */ + +#endif /* _ARBOLOGY_BORDER_ARRAY_H_ */ diff --git a/alib2integrationtest/test-src/tests/borderArrayTest.cpp b/alib2integrationtest/test-src/tests/borderArrayTest.cpp new file mode 100644 index 0000000000..f2a926c6c8 --- /dev/null +++ b/alib2integrationtest/test-src/tests/borderArrayTest.cpp @@ -0,0 +1,54 @@ +#include <catch2/catch.hpp> +#include "testing/TimeoutAqlTest.hpp" + +#include <tree/properties/BorderArrayNaive.h> +#include <tree/properties/BorderArray.h> + +const size_t PATTERN_SIZE = 50; +const size_t PATTERN_HEIGHT = 7; + +const size_t ALPHABET_SIZE = 3; +const size_t RANDOM_ITERATIONS = 100; + +std::string gen ( const std::string & cast, const std::string & var ) { + std::ostringstream oss; + + oss << "execute ( " << cast << " ) tree::generate::RandomRankedPatternFactory "; + oss << "(int) " << PATTERN_HEIGHT << " "; + oss << "(int) " << PATTERN_SIZE << " "; + oss << "(int) " << ALPHABET_SIZE << " "; + oss << "(bool) false "; + oss << "(int) 5"; // rank + oss << " > $" << var; + + return oss.str ( ); +} + +void run ( const std::string & prefixRankedType ) { + ext::vector < std::string > qs = { + gen ( prefixRankedType, "pattern" ), + "execute tree::properties::BorderArrayNaive $pattern > $res1", + "execute tree::properties::BorderArray $pattern > $res2", + // "execute $pattern | string::Compose - ", + // "execute $res1", + // "execute $res2", + "quit compare::VectorCompare $res1 $res2", + }; + for ( size_t i = 0; i < RANDOM_ITERATIONS; i++ ) + TimeoutAqlTest ( 1s, qs ); +} + +TEST_CASE ( "Tree BorderArray", "[integration]" ) { + SECTION ( "PrefixRankedPattern" ) { + run ( "PrefixRankedPattern" ); + } + SECTION ( "PrefixRankedBarPattern" ) { + run ( "PrefixRankedBarPattern" ); + } + SECTION ( "PrefixRankedNonlinearPattern" ) { + run ( "PrefixRankedNonlinearPattern" ); + } + SECTION ( "PrefixRankedBarNonlinearPattern" ) { + run ( "PrefixRankedBarNonlinearPattern" ); + } +} -- GitLab