diff --git a/alib2algo_experimental/src/automaton/RandomAutomatonFactory3.h b/alib2algo_experimental/src/automaton/RandomAutomatonFactory3.h
index 6b883dcfcb39a657405d04475252227887a99e14..e41ec2032a8b4b1a08acce3e37f875a8ad2a4437 100644
--- a/alib2algo_experimental/src/automaton/RandomAutomatonFactory3.h
+++ b/alib2algo_experimental/src/automaton/RandomAutomatonFactory3.h
@@ -200,18 +200,17 @@ automaton::MultiInitialStateNFA < SymbolType, unsigned > RandomAutomatonFactory3
 	ext::vector < unsigned > unused = statesMinimal;
 	unused.erase ( std::find ( unused.begin ( ), unused.end ( ), initialState ) );
 
-	while ( visited.size ( ) != statesMinimal.size ( ) ) {
-		unsigned a = visited [ ext::random_devices::semirandom ( ) % visited.size ( ) ];
+	std::shuffle ( unused.begin ( ), unused.end ( ), ext::random_devices::semirandom );
 
-		if ( automaton.getTransitions ( ).count ( ext::slice_comp ( a ) ) == alphabet.size ( ) )
-			continue;
+	for ( unsigned b : unused ) {
+		unsigned a = * ext::randomValue ( visited.begin ( ), visited.end ( ), ext::random_devices::semirandom, [ & ] ( unsigned candidateState ) {
+			return automaton.getTransitions ( ).count ( ext::slice_comp ( candidateState ) ) != alphabet.size ( );
+		} );
 
 		size_t c = randomSymbol ( a, alphabet, automaton, deterministic );
-		size_t b = ext::random_devices::semirandom ( ) % unused.size ( );
 
-		addTransition( automaton, a, alphabet [ c ], unused [ b ], duplicates );
-		visited.push_back ( unused [ b ] );
-		unused.erase ( unused.begin ( ) + b );
+		addTransition( automaton, a, alphabet [ c ], b, duplicates );
+		visited.push_back ( b );
 	}
 
 	makeRelation ( automaton, alphabet, statesMinimal, statesMinimal, duplicates, density, deterministic );
diff --git a/alib2std/src/extensions/algorithm.hpp b/alib2std/src/extensions/algorithm.hpp
index b883e7e4777ed495ba57dc792b5559ce00f4a086..af56da78eceadf437e1e29bf539d7a22a5355ad8 100644
--- a/alib2std/src/extensions/algorithm.hpp
+++ b/alib2std/src/extensions/algorithm.hpp
@@ -416,5 +416,25 @@ inline bool range_contains_iterator ( ForwardIteratorBegin from, const ForwardIt
 	return false;
 }
 
+template < class Iterator, class RandomDevice >
+Iterator randomValue ( Iterator begin, Iterator end, RandomDevice && r ) {
+	if ( begin == end )
+		throw std::invalid_argument ( "Empty range to pick random value from." );
+	std::advance ( begin, r ( ) % std::distance ( begin, end ) );
+	return begin;
+}
+
+template < class Iterator, class RandomDevice, class Predicate >
+Iterator randomValue ( Iterator begin, Iterator end, RandomDevice r, Predicate p ) {
+	Iterator value = end;
+	size_t incidency = 0;
+
+	for ( ; begin != end; ++ begin )
+		if ( p ( * begin ) && ( r ( ) % ( ++ incidency ) ) < 1 )
+			value = begin;
+
+	return value;
+}
+
 } /* namespace ext */