帶權重的隨機算法及實現

   在遊戲開發過程中,經常會遇到生成一波帶權重的隨機怪物或是掉落List中物品帶權重的情況,總結下我的算法以及實現方法。

直接上代碼

  

using System.Collections.Generic;

using System;





public class RandomHelper

    {


        /// <summary>

        /// 算法:

        /// 1.每個元素權重+1命名爲w,防止爲0情況。

        /// 2.計算出總權重n。

        /// 3.每個元素權重w加上從0到(n-1)的一個隨機數(即總權重以內的隨機數),得到新的權重排序值s。

        /// 4.根據得到新的權重排序值s進行排序,取前面s最大幾個。

        /// </summary>

        /// <param name="list">原始列表</param>

        /// <param name="count">隨機抽取條數</param>

        /// <returns></returns>

    public static List<T> GetRandomList<T>(List<T> list, int count) where T : NormalStageConfig.NormalStageObject.SpawnInitialItem

        {

            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);

        }



    }




    /// <summary>

    /// 權重對象

    /// </summary>

    public class RandomObject

    {

        /// <summary>

        /// 權重

        /// </summary>

        public int Weight { set; get; }

    }


用法思路:寫一箇中轉的類繼承自原類,將原類中的N條數據隨機取出加到新類型的list中即可



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