public class WeightedRandom
{
/// <summary>
/// 带权重的随机
/// </summary>
/// <param name="list">原始列表</param>
/// <param name="count">随机抽取条数</param>
/// <returns></returns>
public static T GetRandomList<T>(List<T> list, int count) where T : RandomObject
{
if (list == null || list.Count <= count || count <= 0)
{
return default(T);
}
//计算权重总和
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++)
{
newList.Add(list[wlist[i].Key]);
}
//随机法则
return newList[0];
}
/// <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);
}
}
public class RandomObject
{
/// <summary>
/// 权重
/// </summary>
public int Weight { set; get; }
}
public class GameItemRandomObject : RandomObject
{
public int item { get; set; }
}
static void Test6()
{
List<GameItemRandomObject> shuidiRanObj = new List<GameItemRandomObject>();
shuidiRanObj.Add(new GameItemRandomObject() { item = 0, Weight = 15 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 1, Weight = 30 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 2, Weight = 1 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 3, Weight = 5 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 4, Weight = 2 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 5, Weight = 12 });
shuidiRanObj.Add(new GameItemRandomObject() { item = 6, Weight = 6 });
var CurItem = WeightedRandom.GetRandomList<GameItemRandomObject>(shuidiRanObj, 1);
}