using System; using System.Collections; using System.Collections.Generic; using Random = System.Random; namespace ET { public static class RandomEx { public static ulong RandUInt64(this Random random) { byte[] byte8 = new byte[8]; random.NextBytes(byte8); return BitConverter.ToUInt64(byte8, 0); } public static int RandInt32(this Random random) { return random.Next(); } public static uint RandUInt32(this Random random) { return (uint)random.Next(); } public static long RandInt64(this Random random) { byte[] byte8 = new byte[8]; random.NextBytes(byte8); return BitConverter.ToInt64(byte8, 0); } } public static class RandomHelper { private static readonly Random random = new Random(Guid.NewGuid().GetHashCode()); public static ulong RandUInt64() { byte[] byte8 = new byte[8]; random.NextBytes(byte8); return BitConverter.ToUInt64(byte8, 0); } public static int RandInt32() { return random.Next(); } public static uint RandUInt32() { return (uint)random.Next(); } public static long RandInt64() { byte[] byte8 = new byte[8]; random.NextBytes(byte8); return BitConverter.ToInt64(byte8, 0); } /// /// 获取lower与Upper之间的随机数,包含下限,不包含上限 /// /// /// /// public static int RandomNumber(int lower, int upper) { int value = random.Next(lower, upper); return value; } public static float RandomFloat() { return (float)random.NextDouble(); } public static float RandomFloat(float min, float max) { int a = RandomNumber((int)(min * 10000), (int)(max * 10000)); return a / 10000f; } public static float RandomFloat01() { int a = RandomNumber(0, 1000000); return a / 1000000f; } public static long NextLong(long minValue, long maxValue) { if (minValue > maxValue) { throw new ArgumentException("minValue is great than maxValue", "minValue"); } long num = maxValue - minValue; return minValue + (long)(random.NextDouble() * num); } public static bool RandomBool() { return random.Next(2) == 0; } public static T RandomArray(this T[] array) { return array[RandomNumber(0, array.Length)]; } public static int RandomArray_Len2(this int[] array) { return RandomHelper.RandomNumber(array[0], array[1]); } public static T RandomArray(this List array) { return array[RandomNumber(0, array.Count)]; } /// /// 打乱数组 /// /// /// 要打乱的数组 public static void BreakRank(this List arr) { if (arr == null || arr.Count < 2) { return; } for (int i = 0; i < arr.Count; i++) { int index = random.Next(0, arr.Count); T temp = arr[index]; arr[index] = arr[i]; arr[i] = temp; } } public static int[] GetRandoms(int sum, int min, int max) { int[] arr = new int[sum]; int j = 0; //表示键和值对的集合。 Hashtable hashtable = new Hashtable(); Random rm = random; while (hashtable.Count < sum) { //返回一个min到max之间的随机数 int nValue = rm.Next(min, max); // 是否包含特定值 if (!hashtable.ContainsValue(nValue)) { //把键和值添加到hashtable hashtable.Add(nValue, nValue); arr[j] = nValue; j++; } } return arr; } /// /// 随机从数组中取若干个不重复的元素, /// 为了降低算法复杂度,所以是伪随机,对随机要求不是非常高的逻辑可以用 /// /// /// /// /// public static bool GetRandListByCount(List sourceList, List destList, int randCount) { if (sourceList == null || destList == null || randCount < 0) { return false; } destList.Clear(); if (randCount >= sourceList.Count) { destList.AddRange(sourceList); return true; } if (randCount == 0) { return true; } int beginIndex = random.Next(0, sourceList.Count - 1); for (int i = beginIndex; i < beginIndex + randCount; i++) { destList.Add(sourceList[i % sourceList.Count]); } return true; } public static void SelectUnits(List sourceList, T selectUnit, int targetCount) { if (sourceList == null || sourceList.Count == 0) return; int sourceCount = sourceList.Count; if (sourceCount <= targetCount) { return; } using var tempList = ListComponent.Create(); using var indexList = ListComponent.Create(); tempList.List.AddRange(sourceList); sourceList.Clear(); for (int i = 0; i < sourceCount; i++) indexList.List.Add(i); int site = sourceCount;//设置下限 for (int j = 0; j < targetCount; j++) { //返回0到site - 1之中非负的一个随机数 int id = RandomHelper.RandomNumber(0, site); //在随机位置取出一个数,保存到结果数组 sourceList.Add(tempList.List[indexList.List[id]]); //最后一个数复制到当前位置 indexList.List[id] = indexList.List[site - 1]; //位置的下限减少一 site--; } if (selectUnit == null || sourceList.Contains(selectUnit)) { return; } sourceList.RemoveAt(0); sourceList.Add(selectUnit); } public static void SelectRandom(List sourceList, int targetCount) { if (sourceList == null || sourceList.Count == 0) return; int sourceCount = sourceList.Count; if (sourceCount <= targetCount) { return; } var tempList = ListComponent.Create(); var indexList = ListComponent.Create(); tempList.List.AddRange(sourceList); sourceList.Clear(); for (int i = 0; i < sourceCount; i++) indexList.List.Add(i); int site = sourceCount;//设置下限 for (int j = 0; j < targetCount; j++) { //返回0到site - 1之中非负的一个随机数 int id = RandomHelper.RandomNumber(0, site); //在随机位置取出一个数,保存到结果数组 sourceList.Add(tempList.List[indexList.List[id]]); //最后一个数复制到当前位置 indexList.List[id] = indexList.List[site - 1]; //位置的下限减少一 site--; } tempList.Dispose(); indexList.Dispose(); } private static int Rand(int n) { // 注意,返回值是左闭右开,所以maxValue要加1 return random.Next(1, n + 1); } /// /// 通过权重随机 /// /// /// public static int RandomByWeight(int[] weights) { int sum = 0; for (int i = 0; i < weights.Length; i++) { sum += weights[i]; } int number_rand = Rand(sum); int sum_temp = 0; for (int i = 0; i < weights.Length; i++) { sum_temp += weights[i]; if (number_rand <= sum_temp) { return i; } } return -1; } public static int RandomByWeight(List weights) { switch (weights.Count) { case 0: return -1; case 1: return 0; } int sum = 0; for (int i = 0; i < weights.Count; i++) { sum += weights[i]; } int number_rand = Rand(sum); int sum_temp = 0; for (int i = 0; i < weights.Count; i++) { sum_temp += weights[i]; if (number_rand <= sum_temp) { return i; } } return -1; } public static int RandomByWeight(List weights, int weightRandomMinVal) { switch (weights.Count) { case 0: return -1; case 1: return 0; } int sum = 0; for (int i = 0; i < weights.Count; i++) { sum += weights[i]; } int number_rand = Rand(Math.Max(sum, weightRandomMinVal)); int sum_temp = 0; for (int i = 0; i < weights.Count; i++) { sum_temp += weights[i]; if (number_rand <= sum_temp) { return i; } } return -1; } public static int RandomByWeight(List weights) { switch (weights.Count) { case 0: return -1; case 1: return 0; } long sum = 0; for (int i = 0; i < weights.Count; i++) { sum += weights[i]; } long number_rand = NextLong(1, sum + 1); long sum_temp = 0; for (int i = 0; i < weights.Count; i++) { sum_temp += weights[i]; if (number_rand <= sum_temp) { return i; } } return -1; } } }