C# 按照比重來隨機 [搬運微調]

原文地址

本文章時在原文章基礎上添加了一丟丟測試代碼

***用途,按照比重來進行隨機

 

測試代碼:

 int viewCount1 = 0;
            int viewCount0 = 0;

            for (int i = 0; i < 5000; i++)
            {
                List<GameItemRandomObject> shuidiRanObj = new List<GameItemRandomObject>();
                shuidiRanObj.Add(new GameItemRandomObject() { item = 0, Weight = 15 });
                shuidiRanObj.Add(new GameItemRandomObject() { item = 1, Weight = 10 });
                var obj = GetRandomList<GameItemRandomObject>(shuidiRanObj, 1)[0].item;
                if (obj.Equals(1)) viewCount1 += 1;
                if (obj.Equals(0)) viewCount0 += 1;
            }
            Console.WriteLine($"五千次測試結果: 0比重15共出現{viewCount0}次,1比重10共出現{viewCount1}次");

 

以下是原文代碼:

 /// <summary>
    /// 權重對象
    /// </summary>
    public class RandomObject
    {
        /// <summary>
        /// 權重
        /// </summary>
        public int Weight { set; get; }
    }
    public class GameItemRandomObject : RandomObject
    {
        public int item { get; set; }
    }
        /// <summary>
        /// 帶權重的隨機
        /// </summary>
        /// <param name="list">原始列表</param>
        /// <param name="count">隨機抽取條數</param>
        /// <returns></returns>
        public static List<T> GetRandomList<T>(List<T> list, int count) where T : RandomObject
        {
            if (list == null || list.Count <= count || count <= 0)
            {
                return list;
            }

            //計算權重總和
            int totalWeights = 0;
            for (int i = 0; i < list.Count; i++)
            {
                totalWeights += list[i].Weight + 1;  //權重+1,防止爲0情況。
            }

            //隨機賦值權重
            System.Random ran = new System.Random(GetRandomSeed());  //GetRandomSeed()隨機種子,防止快速頻繁調用導致隨機一樣的問題 
            List<KeyValuePair<int, int>> wlist = new List<KeyValuePair<int, int>>();    //第一個int爲list下標索引、第一個int爲權重排序值
            for (int i = 0; i < list.Count; i++)
            {
                int w = (list[i].Weight + 1) + ran.Next(0, totalWeights);   // (權重+1) + 從0到(總權重-1)的隨機數
                wlist.Add(new KeyValuePair<int, int>(i, w));
            }

            //排序
            wlist.Sort(
              delegate (KeyValuePair<int, int> kvp1, KeyValuePair<int, int> kvp2)
              {
                  return kvp2.Value - kvp1.Value;
              });

            //根據實際情況取排在最前面的幾個
            List<T> newList = new List<T>();
            for (int i = 0; i < count; i++)
            {
                T entiy = list[wlist[i].Key];
                newList.Add(entiy);
            }

            //隨機法則
            return newList;
        }
        /// <summary>
        /// 隨機種子值
        /// </summary>
        /// <returns></returns>
        private static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章