ShuffleBag (Фишер-Йейтс + PcgRandom)


Ничего, что могло бы быть сделано лучше?

public class ShuffleBag<T> : IEnumerable<T>
{
    private readonly int m_endIndex;
    private readonly FastRandom m_rng;
    private readonly T[] m_values;

    private int m_currentIndex;

    public ShuffleBag(T[] values, ulong state, ulong? stream = null) {
        m_currentIndex = 0;
        m_endIndex = (values.Length - 1);
        m_rng = (stream.HasValue ? new FastRandom(state, stream.Value) : new FastRandom(state));
        m_values = values;
    }
    public ShuffleBag(T[] values) : this(values, SecureRandom.GetUInt64()) { }

    IEnumerator IEnumerable.GetEnumerator() {
        return GetEnumerator();
    }
    public IEnumerator<T> GetEnumerator() {
        var currentIndex = m_currentIndex;
        var endIndex = m_endIndex;
        var rng = m_rng;
        var values = m_values;

        while (currentIndex <= endIndex) {
            var randomIndex = rng.NextInt32(currentIndex, endIndex);
            var temp = values[randomIndex];

            values[randomIndex] = values[currentIndex];
            values[currentIndex] = temp;

            m_currentIndex = currentIndex++;

            yield return temp;
        }
    }
}

Для тех, кто может узнать, вот источник для FastRandom и SecureRandom отобрать.



132
0
задан 12 апреля 2018 в 04:04 Источник Поделиться
Комментарии