Пример #1
0
 private ChainMap InitSimpleChainMapp()
 {
     ChainMap cm = new ChainMap() ;
     cm.AddToChain(new ChainKey(new string[]{null, "word1"}), "valnull") ;
     cm.AddToChain(new ChainKey(new string[]{"word1", "word2"}), "val1") ;
     cm.AddToChain(new ChainKey(new string[]{"word2", "word3"}), "val2") ;
     cm.AddToChain(new ChainKey(new string[]{"word1", "word2"}), "val3") ;
     return cm ;
 }
Пример #2
0
 /// <summary>
 /// Initializes word generator with random seed as parameter
 /// </summary>
 /// <param name="chains"></param>
 /// <param name="rand"> Rng used if better randomness is desired.  The default .NET Rng is 
 /// not completely random </param>
 public WordGenerator(ChainMap chains, Random rand)
 {
     _chains = chains ;
     if(rand != null)
     {
         _rand = rand ;
     }
     else
     {
         _rand = new Random() ;
     }
     Initialize() ;
 }
Пример #3
0
 /// <summary>
 /// Initializes word generator with random seed as parameter
 /// </summary>
 /// <param name="chains"></param>
 /// <param name="rand"> Rng used if better randomness is desired.  The default .NET Rng is
 /// not completely random </param>
 public WordGenerator(ChainMap chains, Random rand)
 {
     _chains = chains;
     if (rand != null)
     {
         _rand = rand;
     }
     else
     {
         _rand = new Random();
     }
     Initialize();
 }
Пример #4
0
        /// <summary>
        /// Generate markov chains using input text
        /// </summary>
        public void GenerateChains()
        {
            //Split text
            string[]      splits         = _text.Split();
            List <string> advancedSplits = new List <string>();

            foreach (string baseSplit in splits)
            {
                advancedSplits.AddRange(StringUtils.SplitAndKeep(baseSplit.ToLower(), _delims));
            }


            Chains = new ChainMap();
            if (advancedSplits.Count < _chainSize * 2)
            {
                throw new Exceptions.InvalidArguments(string.Format("Chain size: {0} to small relative to text split {1}",
                                                                    _chainSize, advancedSplits.Count));
            }

            //Insert null elements in the beginning so chains are created for the first _chainSize elements
            for (int i = 0; i < _chainSize; i++)
            {
                advancedSplits.Insert(0, null);
            }

            List <string> .Enumerator listEnum = advancedSplits.GetEnumerator();

            string[] chainWords = new string[_chainSize];

            for (int i = 0; i < _chainSize; i++)
            {
                listEnum.MoveNext();
                chainWords[i] = listEnum.Current;
            }

            while (listEnum.MoveNext())
            {
                string   current = listEnum.Current;
                ChainKey currKey = new ChainKey(chainWords);
                Chains.AddToChain(currKey, current);

                for (int i = 0; i < _chainSize - 1; i++)
                {
                    chainWords[i] = chainWords[i + 1];
                }
                chainWords[_chainSize - 1] = current;
            }
        }
Пример #5
0
        /// <summary>
        /// Generate markov chains using input text
        /// </summary>
        public void GenerateChains()
        {
            //Split text
            string[] splits = _text.Split() ;
            List<string> advancedSplits = new List<string>() ;
            foreach(string baseSplit in splits)
            {
                advancedSplits.AddRange(StringUtils.SplitAndKeep(baseSplit.ToLower(), _delims)) ;
            }

            Chains = new ChainMap() ;
            if(advancedSplits.Count < _chainSize * 2)
            {
                throw new Exceptions.InvalidArguments(string.Format("Chain size: {0} to small relative to text split {1}",
                                                         _chainSize, advancedSplits.Count)) ;
            }

            //Insert null elements in the beginning so chains are created for the first _chainSize elements
            for(int i = 0 ; i < _chainSize ; i++)
            {
                advancedSplits.Insert(0, null) ;
            }

            List<string>.Enumerator listEnum = advancedSplits.GetEnumerator() ;

            string[] chainWords = new string[_chainSize] ;

            for(int i = 0 ; i < _chainSize ; i++)
            {
                listEnum.MoveNext();
                chainWords[i] = listEnum.Current ;
            }

            while(listEnum.MoveNext())
            {
                string current = listEnum.Current;
                ChainKey currKey = new ChainKey(chainWords) ;
                Chains.AddToChain(currKey, current) ;

                for(int i = 0 ; i < _chainSize - 1 ; i++)
                {
                    chainWords[i] = chainWords[i+1] ;
                }
                chainWords[_chainSize - 1] = current ;
            }
        }
Пример #6
0
        private ChainKey[] CreateKeysArray(ChainMap map, Predicate <ChainKey> keyCondition)
        {
            List <ChainKey> newKeys  = new List <ChainKey>();
            List <ChainKey> origKeys = map.GetAllKeys();

            foreach (ChainKey origKey in origKeys)
            {
                if (keyCondition.Invoke(origKey))
                {
                    //Add key multiple times to ensure probability of picking it is proportional to the
                    //number of values
                    foreach (string val in map.GetValues(origKey))
                    {
                        newKeys.Add(origKey);
                    }
                }
            }
            return(newKeys.ToArray());
        }
Пример #7
0
        /// <summary>
        /// Get subchain of chainkeys and words that satisfies the passed in condition
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        internal ChainMap GetSubChain(ChainCondition condition)
        {
            //If conditions won't be applied return original chains
            if (condition == null || condition == _alwaysTrueCondition ||
                (condition.WordCondition == null && condition.KeyCondition == null))
            {
                return(_chains);
            }

            ChainMap newMap      = new ChainMap();
            bool     valuesFound = false;

            foreach (ChainKey key in _chains.GetAllKeys())
            {
                if (condition.KeyCondition != null)
                {
                    if (condition.KeyCondition.Invoke(key))
                    {
                        foreach (string word in _chains.GetValues(key))
                        {
                            if (condition.WordCondition != null)
                            {
                                if (condition.WordCondition.Invoke(word))
                                {
                                    newMap.AddToChain(key, word);
                                    valuesFound = true;
                                }
                            }
                        }
                    }
                }
            }

            if (!valuesFound)
            {
                throw new Exceptions.NoPossibleElements("Chain map filter filtered everything out");
            }

            return(newMap);
        }
Пример #8
0
 /// <summary>
 /// Compare chain tables ignoring duplicates
 /// </summary>
 public static void CompareChainTablesNoDuplicates(ChainMap inputChainMap1,
     ChainMap inputChainMap2)
 {
     CompareChainTables(GetUnderlyingDictionary(inputChainMap1),
                               GetUnderlyingDictionary(inputChainMap2), true);
 }
Пример #9
0
 public static void CompareChainTables(ChainMap inputChainMap,
     Dictionary<ChainKey, List<string>> inputChains)
 {
     CompareChainTables(GetUnderlyingDictionary(inputChainMap), inputChains) ;
 }
Пример #10
0
        public void T_GetSubChain()
        {
            WordGenerator gen = InitSimpleWordGen() ;

            //Should give me both "hello world one" and "hello world two"
            ChainMap tempMap = gen.GetSubChain(new ChainCondition(cw => cw.Words[0] == "hello", w => w.Length == 3)) ;
            ChainMap correctMap = new ChainMap() ;
            correctMap.AddToChain(new ChainKey(new string[] {"hello", "world"}), "one") ;
            correctMap.AddToChain(new ChainKey(new string[] {"hello", "world"}), "two") ;
            TestUtils.CompareChainTables(correctMap, tempMap) ;

            //Should give me just "hello world one"
            tempMap = gen.GetSubChain(new ChainCondition(cw => cw.Words[0] == "hello", w => w.StartsWith("o"))) ;
            correctMap = new ChainMap() ;
            correctMap.AddToChain(new ChainKey(new string[] {"hello", "world"}), "one") ;
            TestUtils.CompareChainTables(correctMap, tempMap) ;

            //If passed in condition is null nothing should change
            tempMap = gen.GetSubChain(new ChainCondition(null, null)) ;
            TestUtils.CompareChainTables(gen.Chains, tempMap) ;

            //If impossible condition is passed in exception should be thrown
            Assert.Throws(typeof(Exceptions.NoPossibleElements), delegate
                          { gen.GetSubChain(new ChainCondition(null, w => w == "Does not exist")) ;}) ;
        }
Пример #11
0
        public void T_GetRandomKey_WithParams()
        {
            WordGenerator gen = InitSimpleWordGen() ;
            ChainMap subMap = new ChainMap() ;
            ChainKey key1 = new ChainKey(new string[]{"key1", "key2", "key3"}) ;
            ChainKey key2 = new ChainKey(new string[]{"key1", "key2", "key4"}) ;
            subMap.AddToChain(key1, "val1") ;
            subMap.AddToChain(key2, "val2") ;
            bool key1Found, key2Found ;
            key1Found = key2Found = false ;

            for(int i = 0 ; i < 10 ; i++)
            {
                ChainKey currKey = gen.GetRandomKey(subMap);
                if(key1.Equals(currKey))
                {
                    key1Found = true ;
                }
                else if(key2.Equals(currKey))
                {
                    key2Found = true ;
                }
                else
                {
                    Assert.Fail("Invalid key returned") ;
                }
            }
            if(!(key1Found && key2Found))
            {
                Assert.Fail("GetRandomKey is not random") ;
            }
        }
Пример #12
0
 /// <summary>
 /// Get a random key from passed in chain map
 /// The probability of getting a key should be proportional to the number of values
 /// </summary>
 /// <returns></returns>
 internal ChainKey GetRandomKey(ChainMap map)
 {
     ChainKey[] keys = CreateKeysArray(map, _alwaysTrueCondition.KeyCondition) ;
     return keys[_rand.Next(keys.Length)];
 }
Пример #13
0
 /// <summary>
 /// Initializes word generator with default random seed
 /// </summary>
 /// <param name="chains"></param>
 public WordGenerator(ChainMap chains) : this(chains, null)
 {
 }
Пример #14
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;
            //Set null conditions to always true conditions to simplify our code
            if(realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition ;
            //Set on end condition to start condition if it is null
            if(realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions ;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap ;
            //Only generate subchains if we need to
            if(realInitialConditions != _alwaysTrueCondition)
              	{
                initialConditionMap = GetSubChain(realInitialConditions) ;
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition) ;

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys) ;
            string currWord ;
            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord) ;

            if(realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition) ;
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey = currKey;
            _initialConditionSubChains = initialConditionMap ;
            _initialConditionSubKeys = initialConditionSubKeys;
            _currentOnEndCondition = realOnEndCondition;
            SubchainsInitialized = true ;
        }
Пример #15
0
 /// <summary>
 /// Get a random key from passed in chain map
 /// The probability of getting a key should be proportional to the number of values
 /// </summary>
 /// <returns></returns>
 internal ChainKey GetRandomKey(ChainMap map)
 {
     ChainKey[] keys = CreateKeysArray(map, _alwaysTrueCondition.KeyCondition);
     return(keys[_rand.Next(keys.Length)]);
 }
Пример #16
0
 /// <summary>
 /// Get random key from passed in chain map matching passed in condition
 /// </summary>
 /// <param name="map"></param>
 /// <param name="keyCondition"></param>
 /// <returns></returns>
 internal ChainKey GetRandomKey(ChainMap map, Predicate<ChainKey> keyCondition)
 {
     ChainKey[] keys = CreateKeysArray(map, keyCondition) ;
     return keys[_rand.Next(keys.Length)];
 }
Пример #17
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;

            //Set null conditions to always true conditions to simplify our code
            if (realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition;

            //Set on end condition to start condition if it is null
            if (realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap;

            //Only generate subchains if we need to
            if (realInitialConditions != _alwaysTrueCondition)
            {
                initialConditionMap = GetSubChain(realInitialConditions);
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition);

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys);
            string   currWord;

            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord);

            if (realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition);
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey    = currKey;
            _initialConditionSubChains = initialConditionMap;
            _initialConditionSubKeys   = initialConditionSubKeys;
            _currentOnEndCondition     = realOnEndCondition;
            SubchainsInitialized       = true;
        }
Пример #18
0
        /// <summary>
        /// Get subchain of chainkeys and words that satisfies the passed in condition
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        internal ChainMap GetSubChain(ChainCondition condition)
        {
            //If conditions won't be applied return original chains
            if(condition == null || condition == _alwaysTrueCondition ||
               (condition.WordCondition == null && condition.KeyCondition == null))
            {
                return _chains ;
            }

            ChainMap newMap = new ChainMap() ;
            bool valuesFound = false ;
            foreach(ChainKey key in _chains.GetAllKeys())
            {
                if(condition.KeyCondition != null)
                {
                    if(condition.KeyCondition.Invoke(key))
                    {
                        foreach(string word in _chains.GetValues(key))
                        {
                            if(condition.WordCondition != null)
                            {
                                if(condition.WordCondition.Invoke(word))
                                {
                                    newMap.AddToChain(key, word) ;
                                    valuesFound = true ;
                                }
                            }
                        }
                    }
                }
            }

            if(!valuesFound)
            {
                throw new Exceptions.NoPossibleElements("Chain map filter filtered everything out") ;
            }

            return newMap ;
        }
Пример #19
0
 /// <summary>
 /// Initializes word generator with default random seed
 /// </summary>
 /// <param name="chains"></param>
 public WordGenerator(ChainMap chains)
     : this(chains, null)
 {
 }
Пример #20
0
 public static Dictionary<ChainKey, List<string>> GetUnderlyingDictionary(ChainMap inputChainMap)
 {
     Dictionary<ChainKey, List<string>> retValues = new Dictionary<ChainKey, List<string>>() ;
     List<ChainKey> keys = inputChainMap.GetAllKeys() ;
     foreach(ChainKey key in keys)
     {
         retValues.Add(key, inputChainMap.GetValues(key)) ;
     }
     return retValues;
 }
Пример #21
0
 /// <summary>
 /// Get random key from passed in chain map matching passed in condition
 /// </summary>
 /// <param name="map"></param>
 /// <param name="keyCondition"></param>
 /// <returns></returns>
 internal ChainKey GetRandomKey(ChainMap map, Predicate <ChainKey> keyCondition)
 {
     ChainKey[] keys = CreateKeysArray(map, keyCondition);
     return(keys[_rand.Next(keys.Length)]);
 }
Пример #22
0
 private ChainKey[] CreateKeysArray(ChainMap map, Predicate<ChainKey> keyCondition)
 {
     List<ChainKey> newKeys = new List<ChainKey>() ;
     List<ChainKey> origKeys = map.GetAllKeys() ;
     foreach(ChainKey origKey in origKeys)
     {
         if(keyCondition.Invoke(origKey))
         {
             //Add key multiple times to ensure probability of picking it is proportional to the
             //number of values
             foreach(string val in map.GetValues(origKey))
             {
                 newKeys.Add(origKey) ;
             }
         }
     }
     return newKeys.ToArray() ;
 }