Exemplo n.º 1
0
        /// <summary>
        /// Adds items to the Markov chain, including termini.
        /// </summary>
        /// <param name="items">The items to add.</param>
        public void AddItems(IEnumerable <T> items)
        {
            Queue <T> previous = new Queue <T>();

            // Add each item to the chain.
            foreach (T item in items)
            {
                AddItem(previous, item);

                previous.Enqueue(item);
                if (previous.Count > order)
                {
                    previous.Dequeue();
                }
            }

            // Add to the terminal weights
            MarkovNode <T> key = new MarkovNode <T>(previous);

            if (!terminalWeights.ContainsKey(key))
            {
                terminalWeights.Add(key, 0);
            }
            terminalWeights[key]++;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets an series of items, generated from the Markov chain.
        /// </summary>
        /// <returns>An IEnumerable of items.</returns>
        public IEnumerable <T> Generate()
        {
            Random    random   = new Random();
            Queue <T> previous = new Queue <T>();

            while (true)
            {
                while (previous.Count > order)
                {
                    previous.Dequeue();
                }

                MarkovNode <T> key = new MarkovNode <T>(previous);

                Dictionary <T, int> weights;
                // If terminus is reached.
                if (!chain.TryGetValue(key, out weights))
                {
                    yield break;
                }

                int terminalWeight = 0;
                terminalWeights.TryGetValue(key, out terminalWeight);

                int sumWeights  = weights.Sum(w => w.Value);
                int randomValue = random.Next(sumWeights + terminalWeight) + 1;

                // If terminus is chosen.
                if (randomValue > sumWeights)
                {
                    yield break;
                }

                // Loop through the chain, adding the weights of each step.
                // When 'randomValue' is less than or equal to the cumulative
                // weights so far, the current item is chosen.
                int cumulativeWeight = 0;
                foreach (var pair in weights)
                {
                    cumulativeWeight += pair.Value;
                    if (randomValue <= cumulativeWeight)
                    {
                        yield return(pair.Key);

                        previous.Enqueue(pair.Key);
                        break;
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Adds an item to the Markov chain.
        /// </summary>
        /// <param name="previous">The previous items in the chain.</param>
        /// <param name="item">The item to add.</param>
        private void AddItem(Queue <T> previous, T item)
        {
            if (previous.Count > order)
            {
                throw new ArgumentException("The queue is longer than the Markov chain order", "previous");
            }

            MarkovNode <T> key = new MarkovNode <T>(previous);

            if (!chain.ContainsKey(key))
            {
                chain.Add(key, new Dictionary <T, int>());
            }
            if (!chain[key].ContainsKey(item))
            {
                chain[key].Add(item, 0);
            }
            chain[key][item]++;
        }
Exemplo n.º 4
0
        public bool Equals(MarkovNode <T> other)
        {
            if (other == null)
            {
                return(false);
            }

            if (items.Length != other.items.Length)
            {
                return(false);
            }

            for (int i = 0; i < items.Length; i++)
            {
                if (!items[i].Equals(other.items[i]))
                {
                    return(false);
                }
            }

            return(true);
        }