diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.cpp b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
index 0f986bddd7f956ea4a2b51119295feec633d2e9f..9bb7cffe5df2593bde0fb9ee067f55b74bbe1b40 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.cpp
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.cpp
@@ -19,20 +19,19 @@
 #include <random>
 
 #include <alphabet/SubtreeWildcardSymbol.h>
+#include <alphabet/NonlinearVariableSymbol.h>
 #include <exception/CommonException.h>
 
 namespace tree {
 
 namespace generate {
 
-int c = 0;
-
 struct Node {
-	char   symbol;
-	int	   depth;
+	char symbol;
+	int depth;
 	Node * right;
 	Node * child = NULL;
-	int	   rank	 = 0;
+	int rank = 0;
 
 	Node ( ) : depth ( 0 ) { }
 	Node ( Node * parent ) : depth ( parent->depth + 1 ) {
@@ -161,6 +160,22 @@ struct Node {
 		}
 	}
 
+	RankedNode createRankedNonlinearPatternNode ( ) {
+		if ( rank == 0 ) {
+			return RankedNode ( alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::NonlinearVariableSymbol ( symbol ) ), 0 ), { } );
+		} else {
+			std::vector < std::smart_ptr < RankedNode > > children;
+			Node * nextChild = child;
+
+			for ( int i = 0; i < rank; i++ ) {
+				children.emplace_back ( std::make_smart < RankedNode > ( nextChild->createRankedNonlinearPatternNode ( ) ) );
+				nextChild = nextChild->right;
+			}
+
+			return RankedNode ( alphabet::RankedSymbol ( symbol, rank ), std::move ( children ) );
+		}
+	}
+
 	void nicePrint ( std::ostream & os = std::cout, const std::string & prefix = "", const bool last = true ) const {
 		os << prefix;
 
@@ -271,8 +286,8 @@ UnrankedTree RandomTreeFactory::generateUnrankedTree ( int depth, int nodesCount
 
 	std::set < alphabet::Symbol > treeAlphabet;
 
-	for ( std::vector < char >::const_iterator it = alphabet.begin ( ); it != alphabet.end ( ); ++it )
-		treeAlphabet.insert ( alphabet::symbolFrom ( * it ) );
+	for ( char it : alphabet )
+		treeAlphabet.insert ( alphabet::symbolFrom ( it ) );
 
 	UnrankedTree tree ( treeAlphabet, root->createUnrankedNode ( ) );
 	delete root;
@@ -307,12 +322,9 @@ RankedTree RandomTreeFactory::generateRankedTree ( int depth, int nodesCount, in
 
 	std::set < alphabet::RankedSymbol > treeRankedAlphabet;
 
-	for ( std::map < int, std::vector < char > >::const_iterator it = rankedAlphabet.begin ( ); it != rankedAlphabet.end ( ); ++it ) {
-		const std::vector < char > & alphabet = it->second;
-
-		for ( std::vector < char >::const_iterator i = alphabet.begin ( ); i != alphabet.end ( ); ++i )
-			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( * i, it->first ) );
-	}
+	for ( const std::pair < int, std::vector < char > > & it : rankedAlphabet )
+		for ( char i : it.second )
+			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( i, it.first ) );
 
 	RankedTree tree ( treeRankedAlphabet, root->createRankedNode ( ) );
 	delete root;
@@ -329,12 +341,9 @@ RankedPattern RandomTreeFactory::generateRankedPattern ( int depth, int nodesCou
 
 	std::set < alphabet::RankedSymbol > treeRankedAlphabet;
 
-	for ( std::map < int, std::vector < char > >::const_iterator it = rankedAlphabet.begin ( ); it != rankedAlphabet.end ( ); ++it ) {
-		const std::vector < char > & alphabet = it->second;
-
-		for ( std::vector < char >::const_iterator i = alphabet.begin ( ); i != alphabet.end ( ); ++i )
-			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( * i, it->first ) );
-	}
+	for ( const std::pair < int, std::vector < char > > & it : rankedAlphabet )
+		for ( char i : it.second )
+			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( i, it.first ) );
 
 	alphabet::RankedSymbol subtreeWildcard ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 );
 	treeRankedAlphabet.insert ( subtreeWildcard );
@@ -343,6 +352,32 @@ RankedPattern RandomTreeFactory::generateRankedPattern ( int depth, int nodesCou
 	return tree;
 }
 
+RankedNonlinearPattern RandomTreeFactory::generateRankedNonlinearPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank ) {
+	Node * root = generateTreeStructure ( depth, nodesCount, maxRank );
+	std::map < int, std::vector < char > > rankedAlphabet;
+
+	root->fillRanks ( rankedAlphabet );
+	generateRankedAlphabet ( rankedAlphabet, maxAlphabetSize, randomizedAlphabet );
+	root->generateRankedSymbols ( rankedAlphabet );
+
+	std::set < alphabet::RankedSymbol > treeRankedAlphabet;
+	std::set < alphabet::RankedSymbol > nonlinearVariables;
+
+	for ( const std::pair < int, std::vector < char > > & it : rankedAlphabet )
+		for ( char i : it.second )
+			treeRankedAlphabet.insert ( alphabet::RankedSymbol ( i, it.first ) );
+
+	for ( char i : rankedAlphabet [ 0 ] )
+		nonlinearVariables.insert ( alphabet::RankedSymbol ( alphabet::Symbol ( alphabet::NonlinearVariableSymbol ( i ) ), 0 ) );
+
+	alphabet::RankedSymbol subtreeWildcard ( alphabet::Symbol ( alphabet::SubtreeWildcardSymbol::SUBTREE_WILDCARD ), 0 );
+	treeRankedAlphabet.insert ( subtreeWildcard );
+	treeRankedAlphabet.insert ( nonlinearVariables.begin ( ), nonlinearVariables.end ( ) );
+	RankedNonlinearPattern tree ( std::move ( subtreeWildcard ), nonlinearVariables, treeRankedAlphabet, root->createRankedNonlinearPatternNode ( ) );
+	delete root;
+	return tree;
+}
+
 } /* namespace generate */
 
 } /* namespace automaton */
diff --git a/alib2algo/src/tree/generate/RandomTreeFactory.h b/alib2algo/src/tree/generate/RandomTreeFactory.h
index c60d90d8769d34e91c47c5c5e4da43571f34c819..e292858142416cef57c565943480638b995d39f6 100644
--- a/alib2algo/src/tree/generate/RandomTreeFactory.h
+++ b/alib2algo/src/tree/generate/RandomTreeFactory.h
@@ -16,6 +16,7 @@
 #include <alphabet/LabeledSymbol.h>
 #include <tree/ranked/RankedTree.h>
 #include <tree/ranked/RankedPattern.h>
+#include <tree/ranked/RankedNonlinearPattern.h>
 #include <tree/unranked/UnrankedTree.h>
 #include <tree/unranked/UnrankedPattern.h>
 
@@ -27,6 +28,7 @@ class RandomTreeFactory {
 public:
 	static tree::RankedTree generateRankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 	static tree::RankedPattern generateRankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
+	static tree::RankedNonlinearPattern generateRankedNonlinearPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 	static tree::UnrankedTree generateUnrankedTree ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 	static tree::UnrankedPattern generateUnrankedPattern ( int depth, int nodesCount, int maxAlphabetSize, bool randomizedAlphabet, int maxRank = INT_MAX );
 
diff --git a/arand2/src/arand.cpp b/arand2/src/arand.cpp
index c12fd9d6b1cb0b0b23d6560698d0598a0eedeb42..f69cd404e1c92fa24445b911129b3af396cdc204 100644
--- a/arand2/src/arand.cpp
+++ b/arand2/src/arand.cpp
@@ -36,6 +36,7 @@ int main ( int argc, char * argv[] ) {
 		allowed.push_back ( "UP" );
 		allowed.push_back ( "RT" );
 		allowed.push_back ( "RP" );
+		allowed.push_back ( "RNP" );
 		TCLAP::ValuesConstraint < std::string > allowedVals ( allowed );
 
 		TCLAP::ValueArg < std::string > type ( "t", "type", "Type of generated structure", true, "FSM", & allowedVals );
@@ -185,6 +186,15 @@ int main ( int argc, char * argv[] ) {
 			measurements::end ( );
 			measurements::start ( "Output write", measurements::Type::AUXILIARY );
 
+			alib::XmlDataFactory::toStdout ( res );
+		} else if ( type.getValue ( ) == "RNP" ) {
+			measurements::start ( "Algorithm", measurements::Type::MAIN );
+
+			tree::RankedNonlinearPattern res = tree::generate::RandomTreeFactory::generateRankedNonlinearPattern ( height.getValue ( ), nodes.getValue ( ), alphabetSize.getValue ( ), randomizedAlphabet.getValue ( ), maxRank.getValue ( ) );
+
+			measurements::end ( );
+			measurements::start ( "Output write", measurements::Type::AUXILIARY );
+
 			alib::XmlDataFactory::toStdout ( res );
 		} else {
 			throw exception::CommonException ( "Invalid type." );