提高随机数不重复概率的种子生成方法:
Unity写法:
Random.InitState(seed);
seed = (int)System.DateTime.Now.Ticks;
if (isFirstMeet)
{
Num = Random.Range(1, 3);//1-2
}
C#写法:
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 );
}
Random random = new Random( GetRandomSeed( ) );
使用算法和数据结构产生不重复随机数方法:
- 方法一
private List<int> temp_List = new List<int>();
private int[] target_num = new int[] {100, 200, 300, 400, 500, 600, 700, 800, 900};
private int GetRandomNum()
{
int rangeI;
do
{
rangeI = UnityEngine.Random.Range(0, target_num.Length);
//注意这里边界
if (temp_List.Count >= target_num.Length)
{
temp_List.Clear();
}
}
while (isContains(rangeI));
return target_num[rangeI];
}
private bool isContains(int rangi)
{
for (int m = 0; m < temp_List.Count; m++)
{
if (temp_List[m] == rangi)
return true;
}
temp_List.Add(rangi);
return false;
}
public void OnClickBtn()
{
Debug.Log(GetRandomNum());
}
测试结果
全部都随机一遍之后才会重新从头随机
上面的方法实际就是使用双数组的方法类确保随机不重复。下面是更简洁的写法:
/// <summary>
/// 方法一 使用随机抽取数组index中的数,填充在新的数组array中,使数组array中的数是随机的
/// 方法一思路:用一个数组来保存索引号,先随机生成一个数组位置,然后把随机抽取到的位置的索引号取出来,
/// 并把最后一个索引号复制到当前的数组位置,然后使随机数的上限减一,具体如:先把这100个数放在一个数组内,
/// 每次随机取一个位置(第一次是1-100,第二次是1-99,...),将该位置的数用最后的数代替。
/// </summary>
static int[] UseDoubleArrayToNonRepeatedRandom(int length, int minValue, int maxValue)
{
int seed = Guid.NewGuid().GetHashCode();
Random radom = new Random(seed);
int[] index = new int[length];
for (int i = 0; i < length; i++)
{
index[i] = i + 1;
}
int[] array = new int[length]; // 用来保存随机生成的不重复的数
int site = length; // 设置上限
int idx; // 获取index数组中索引为idx位置的数据,赋给结果数组array的j索引位置
for (int j = 0; j < length; j++)
{
idx = radom.Next(0, site - 1); // 生成随机索引数
array[j] = index[idx]; // 在随机索引位置取出一个数,保存到结果数组
index[idx] = index[site - 1]; // 作废当前索引位置数据,并用数组的最后一个数据代替之
site--; // 索引位置的上限减一(弃置最后一个数据)
}
return array;
}
- 方法二
/// <summary>
/// 检查生成的随机数据是否重复
/// 如果重复则继续递归调用
/// 如果不重复则返回该数
/// </summary>
/// <param name="arr">生成的非重复随机数数组</param>
/// <param name="temp">随机数</param>
/// <param name="minValue">最大值</param>
/// <param name="maxValue">最小值</param>
/// <param name="random">生成随机数对象</param>
/// <returns>返回一个不重复的随机数</returns>
static int getNumberNonRepeatedRandom(int[] arr, int temp, int minValue, int maxValue, Random random)
{
int n = 0;
while (n <= arr.Length - 1)
{
if (arr[n] == temp) //利用循环判断是否有重复
{
temp = random.Next(minValue, maxValue); //重新随机获取。
getNumberNonRepeatedRandom(arr, temp, minValue, maxValue, random);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。
}
n++;
}
return temp;
}
/// <summary>
/// 递归,用它来检测生成的随机数是否有重复,如果取出来的数字和已取得的数字有重复就重新随机获取。
/// </summary>
static int[] RecursiveMethodToNonRepeatedRandom(int length, int minValue, int maxValue)
{
int seed = Guid.NewGuid().GetHashCode();
Random random = new Random(seed);
int[] array = new int[length];
int temp = 0;
for (int i = 0; i < length; i++)
{
temp = random.Next(minValue, maxValue); // 随机取数
array[i] = getNumberNonRepeatedRandom(array, temp, minValue, maxValue, random); // 取出值赋到数组中
}
return array;
}
- 方法三
/// <summary>
/// 利用Hashtable
/// </summary>
static int[] UseHashTableToNonRepeatedRandom(int length, int minValue, int maxValue)
{
Hashtable hashtable = new Hashtable();
int seed = Guid.NewGuid().GetHashCode();
Random random = new Random(seed);
for (int i = 0; hashtable.Count < length; i++)
{
int nValue = random.Next(minValue, maxValue);
if (!hashtable.ContainsValue(nValue) && nValue != 0)
{
hashtable.Add(i, nValue);
//hashtable.Add(nValue, nValue); // 将 key 和 value设置成一样的值,导致hashtable无法按添加顺序输出数组
//Console.WriteLine(nValue.ToString());
}
}
int[] array = new int[hashtable.Count];
hashtable.Values.CopyTo(array, 0);
return array;
}
网友评论