/* * RandomRegExpFactory.cpp * * Created on: 27. 3. 2014 * Author: Jan Travnicek */ #include "RandomRegExpFactory.h" #include <regexp/unbounded/UnboundedRegExpElements.h> #include <exception/CommonException.h> #include <alib/algorithm> #include <alib/random> #include <registration/AlgoRegistration.hpp> namespace regexp { namespace generate { regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, size_t alphabetSize, bool randomizedAlphabet ) { if(alphabetSize > 26) throw exception::CommonException("Too big alphabet."); if( alphabetSize <= 0 ) throw exception::CommonException( "Alphabet size must be greater than 0." ); ext::vector<DefaultSymbolType> symbols; for(int i = 0; i < 26; i++) symbols.push_back(DefaultSymbolType((char)(i + 'a'))); if(randomizedAlphabet) shuffle(symbols.begin(), symbols.end(), ext::random_devices::semirandom); ext::set<DefaultSymbolType> alphabet(symbols.begin(), symbols.begin() + alphabetSize); return RandomRegExpFactory::generateUnboundedRegExp( leafNodes, height, alphabet ); } auto GenerateUnboundedRegExp1 = registration::AbstractRegister < RandomRegExpFactory, regexp::UnboundedRegExp < >, size_t, size_t, size_t, bool > ( RandomRegExpFactory::generateUnboundedRegExp, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "leafNodes", "height", "alphabetSize", "randomizedAlphabet" ); regexp::UnboundedRegExp < > RandomRegExpFactory::generateUnboundedRegExp( size_t leafNodes, size_t height, ext::set<DefaultSymbolType> alphabet) { if( alphabet.size() > 26) throw exception::CommonException("Too big alphabet."); if( alphabet.size() <= 0 ) throw exception::CommonException( "Alphabet size must be greater than 0." ); ext::ptr_vector < regexp::UnboundedRegExpElement < DefaultSymbolType > > elems; { elems.push_back ( regexp::UnboundedRegExpEmpty < DefaultSymbolType > ( ) ); elems.push_back ( regexp::UnboundedRegExpEpsilon < DefaultSymbolType > ( ) ); } if(alphabet.size() > 6) { elems.push_back ( regexp::UnboundedRegExpEmpty < DefaultSymbolType > ( ) ); elems.push_back ( regexp::UnboundedRegExpEpsilon < DefaultSymbolType > ( ) ); } if(alphabet.size() > 16) { elems.push_back ( regexp::UnboundedRegExpEmpty < DefaultSymbolType > ( ) ); elems.push_back ( regexp::UnboundedRegExpEpsilon < DefaultSymbolType > ( ) ); } for ( const DefaultSymbolType & symbol : alphabet) { elems.push_back ( regexp::UnboundedRegExpSymbol < DefaultSymbolType > ( symbol ) ); } regexp::UnboundedRegExp < > res = RandomRegExpFactory::SimpleUnboundedRegExp( leafNodes, height, elems ); return res; } auto GenerateUnboundedRegExp2 = registration::AbstractRegister < RandomRegExpFactory, regexp::UnboundedRegExp < >, size_t, size_t, ext::set < DefaultSymbolType > > ( RandomRegExpFactory::generateUnboundedRegExp, abstraction::AlgorithmCategories::AlgorithmCategory::DEFAULT, "leafNodes", "height", "alphabet" ); regexp::UnboundedRegExp < > RandomRegExpFactory::SimpleUnboundedRegExp( size_t n, size_t h, const ext::ptr_vector < regexp::UnboundedRegExpElement < DefaultSymbolType > > & elems) { return regexp::UnboundedRegExp < > (regexp::UnboundedRegExpStructure < DefaultSymbolType > ( SimpleUnboundedRegExpElement (n, h, elems))); } ext::ptr_value < regexp::UnboundedRegExpElement < DefaultSymbolType > > RandomRegExpFactory::SimpleUnboundedRegExpElement (size_t n, size_t h, const ext::ptr_vector < regexp::UnboundedRegExpElement < DefaultSymbolType > > & elems) { if(h == 0 || n == 0) { return ext::ptr_value < UnboundedRegExpElement < DefaultSymbolType > > ( elems [ ext::random_devices::semirandom ( ) % elems.size ( ) ] ); } else { unsigned childNodes = ext::random_devices::semirandom() % 10; if(childNodes < 4) childNodes = 1; else if(childNodes < 6) childNodes = 2; else if(childNodes < 8) childNodes = 3; else childNodes = 4; childNodes = childNodes > n ? n : childNodes; int subSizes[4]; if(childNodes == 4) { subSizes[3] = ext::random_devices::semirandom() % ( n - 1 ); subSizes[2] = ext::random_devices::semirandom() % ( n - subSizes[3] - 1 ); subSizes[1] = ext::random_devices::semirandom() % ( n - subSizes[2] - subSizes [3] - 1 ); subSizes[3] += 1; subSizes[2] += 1; subSizes[1] += 1; subSizes[0] = n - subSizes[1] - subSizes[2] - subSizes[3]; } if(childNodes == 3) { subSizes[2] = ext::random_devices::semirandom() % ( n - 1); subSizes[1] = ext::random_devices::semirandom() % ( n - subSizes[2] - 1); subSizes[2] += 1; subSizes[1] += 1; subSizes[0] = n - subSizes[1] - subSizes[2]; } if(childNodes == 2) { subSizes[1] = ext::random_devices::semirandom() % ( n - 1 ); subSizes[1] += 1; subSizes[0] = n - subSizes[1]; } if(childNodes == 1) { return ext::ptr_value < regexp::UnboundedRegExpElement < DefaultSymbolType > > ( regexp::UnboundedRegExpIteration < DefaultSymbolType > (SimpleUnboundedRegExpElement ( n, h - 1, elems ) ) ); } int nodeType = ext::random_devices::semirandom() % 2; if(nodeType == 0) { regexp::UnboundedRegExpConcatenation < DefaultSymbolType > con; for ( unsigned i = 0; i < childNodes; i ++ ) { con.appendElement ( std::move ( SimpleUnboundedRegExpElement ( subSizes [ i ], h - 1, elems ) ) ); } return ext::ptr_value < regexp::UnboundedRegExpElement < DefaultSymbolType > > ( std::move ( con ) ); } else { regexp::UnboundedRegExpAlternation < DefaultSymbolType > alt; for ( unsigned i = 0; i < childNodes; i ++) { alt.appendElement ( std::move ( SimpleUnboundedRegExpElement ( subSizes [ i ], h - 1, elems ) ) ); } return ext::ptr_value < regexp::UnboundedRegExpElement < DefaultSymbolType > > ( std::move ( alt ) ); } } } } /* namespace generate */ } /* namespace regexp */