/// <summary> /// Adds the items to the generator with the weight specified. /// </summary> /// <param name="items">The items to add to the generator.</param> /// <param name="weight">The weight at which to add the items.</param> public void Add(IEnumerable <T> items, int weight) { if (items == null) { throw new ArgumentNullException(nameof(items)); } var previous = new Queue <T>(); foreach (var item in items) { var key = new ChainState <T>(previous); this.Add(key, item, weight); previous.Enqueue(item); if (previous.Count > this.order) { previous.Dequeue(); } } var terminalKey = new ChainState <T>(previous); var newWeight = Math.Max(0, this.terminals.ContainsKey(terminalKey) ? weight + this.terminals[terminalKey] : weight); if (newWeight == 0) { this.terminals.Remove(terminalKey); } else { this.terminals[terminalKey] = newWeight; } }
/// <summary> /// Gets the weights of termination following from the specified state. /// </summary> /// <param name="state">The state preceding the items of interest.</param> /// <returns>A dictionary of the items and their weight.</returns> public int GetTerminalWeight(ChainState <T> state) { this.terminals.TryGetValue(state, out var weight); return(weight); }
/// <summary> /// Adds the item to the generator, with the specified state preceding it. /// </summary> /// <param name="state">The state preceding the item.</param> /// <param name="next">The item to add.</param> /// <remarks> /// See <see cref="MarkovChain{T}.Add(ChainState{T}, T, int)"/> for remarks. /// </remarks> public void Add(ChainState <T> state, T next) => this.Add(state, next, 1);