/// <summary>
        /// Returns an item chosen randomly by weight (higher weights are more likely),
        /// and replaces it so that it can be chosen again
        /// </summary>
        public TKey NextWithReplacement()
        {
            VerifyHaveItemsToChooseFrom();

            Node currentNode  = _root;
            long randomNumber = _random.NextLong(0, TotalWeight) + 1;  //[1, TotalWeight] inclusive

            while (true)
            {
                if (currentNode.left.subtreeWeight >= randomNumber)
                {
                    currentNode = currentNode.left;
                }
                else
                {
                    randomNumber -= currentNode.left.subtreeWeight;
                    if (currentNode.right.subtreeWeight >= randomNumber)
                    {
                        currentNode = currentNode.right;
                    }
                    else
                    {
                        return(currentNode.key);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Returns an item chosen randomly by weight (higher weights are more likely),
        /// and replaces it so that it can be chosen again
        /// </summary>
        public TKey NextWithReplacement()
        {
            VerifyHaveItemsToChooseFrom();

            if (_listNeedsRebuilding)
            {
                RebuildProbabilityList();
            }

            //Choose a random box, then flip a biased coin (represented by choosing a number of balls within the box)
            int  randomIndex    = _random.Next(_probabilityBoxes.Count);
            long randomNumBalls = _random.NextLong(_heightPerBox) + 1;

            if (randomNumBalls <= _probabilityBoxes[randomIndex].NumBallsInBox)
            {
                return(_probabilityBoxes[randomIndex].Key);
            }
            else
            {
                return(_probabilityBoxes[randomIndex].Alias);
            }
        }