/// <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(); } } this.AddTerminalInternal(new ChainState <T>(previous), weight); }
/// <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; } }
/// <inheritdoc/> public override void Add(ChainState <T> state, T next, int weight) { if (state == null) { throw new ArgumentNullException(nameof(state)); } for (var orderTarget = this.Order; orderTarget >= 1; orderTarget--) { if (orderTarget == this.Order) { base.Add(state, next, weight); } else { if (orderTarget < state.Count) { state = new ChainState <T>(state.Skip(state.Count - orderTarget)); } this.chains[this.Order - orderTarget - 1].Add(state, next, weight); } } }
private int GetDesiredOrderTarget(ref ChainState <T> state, out Dictionary <T, int> nextStates) { for (var orderTarget = this.Order; ; orderTarget--) { if (orderTarget == this.Order) { nextStates = base.GetNextStatesInternal(state); } else { if (orderTarget < state.Count) { state = new ChainState <T>(state.Skip(state.Count - orderTarget)); } nextStates = this.chains[this.Order - orderTarget - 1].GetNextStatesInternal(state); } if (nextStates?.Count >= this.desiredNumNextStates || orderTarget <= 1) { return(orderTarget); } } }
/// <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);
/// <summary> /// Gets the items from the generator that follow from the specified state preceding it without copying the values. /// </summary> /// <param name="state">The state preceding the items of interest.</param> /// <returns>The raw dictionary of the items and their weight.</returns> protected internal virtual Dictionary <T, int> GetNextStatesInternal(ChainState <T> state) => this.items.TryGetValue(state, out var weights) ? weights : null;
/// <summary> /// Gets the items from the generator that follow from the specified state preceding it. /// </summary> /// <param name="state">The state preceding the items of interest.</param> /// <returns>A dictionary of the items and their weight.</returns> public Dictionary <T, int> GetNextStates(ChainState <T> state) { var weights = this.GetNextStatesInternal(state); return(weights != null ? new Dictionary <T, int>(weights) : null); }
/// <inheritdoc/> protected internal override Dictionary <T, int> GetNextStatesInternal(ChainState <T> state) { this.GetDesiredOrderTarget(ref state, out var nextStates); return(nextStates); }