C# 帶權重的隨機 與 不帶權重的隨機
阿新 • • 發佈:2019-02-04
帶權重的隨機:
/// <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);
}
使用例子:
/// <summary>
/// 權重物件
/// </summary>
public class RandomObject
{
/// <summary>
/// 權重
/// </summary>
public int Weight { set; get; }
}
public class GameItemRandomObject : RandomObject
{
public int item { get; set; }
}
List<GameItemRandomObject> shuidiRanObj = new List<GameItemRandomObject>();
shuidiRanObj.Add(new GameItemRandomObject() { item = 0, Weight = 15 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 1, Weight = 10 });
CurItem = MyExtansion.GetRandomList<GameItemRandomObject>(shuidiRanObj, 1)[0].item;
不帶權重的隨機:
/// <summary>
/// 產生從0開始的隨機數
/// </summary>
/// <param name="sum">需要的隨機數的個數</param>
/// <param name="max">隨機的最大值,不會等於最大值</param>
/// <returns></returns>
public static int[] GetRandoms(int sum, int max)
{
max++;
if (max < 1)
{
LogTool.LogError("GetRandoms Error: max <= 1");
return null;
}
int[] arr = new int[sum];
int j = 0;
//表示鍵和值對的集合。
Hashtable hashtable = new Hashtable();
System.Random rm = new System.Random();
for (int i = 0; hashtable.Count < sum; i++)
{
//返回一個小於所指定最大值的非負隨機數
int nValue = rm.Next(max);
//containsValue(object value) 是否包含特定值
if (!hashtable.ContainsValue(nValue) && nValue != 0)
{
//把鍵和值新增到hashtable
hashtable.Add(nValue, nValue);
//Debug.Log(i);
arr[j] = nValue;
j++;
}
}
int temp;
//最多做n-1趟排序
for (int i = 0; i < arr.Length - 1; i++)
{
//對當前無序區間score[0......length-i-1]進行排序(j的範圍很關鍵,這個範圍是在逐步縮小的)
for (j = 0; j < arr.Length - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for(int i =0;i< arr.Length; i++)
{
arr[i]--;
}
return arr;
}
【個人廣告】
希望大家可以支援我的個人微訊號“小遊戲情報局”