Archived
添加基础枚举扩展
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static partial class MacroMath
|
||||
{
|
||||
#region 洗牌算法
|
||||
|
||||
/// <summary>
|
||||
/// Fisher-Yates洗牌算法,时间复杂度为O(n*n),空间复杂度为O(n)
|
||||
/// </summary>
|
||||
/// <param name="length">待选项目的索引长度</param>
|
||||
/// <param name="select">输出项目的索引长度</param>
|
||||
/// <returns></returns>
|
||||
public static List<int> FisherYatesShuffle(int length, int select)
|
||||
{
|
||||
var random = new System.Random();
|
||||
|
||||
List<int> arr = Enumerable.Range(1, length).ToList();
|
||||
List<int> res = new List<int>();
|
||||
|
||||
for(int i = 0; i < select; ++i)
|
||||
{
|
||||
int k = random.Next(arr.Count);
|
||||
res.Add(arr[k]);
|
||||
arr.RemoveAt(k);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 蓄水池抽样算法,可以在线程安全的情况下完成洗牌。
|
||||
/// </summary>
|
||||
/// <param name="arr"></param>
|
||||
/// <param name="select">需要抽取的样本 M</param>
|
||||
/// <param name="reservoir"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
public static void ReservoirSampling(List<int> arr, int select, ConcurrentBag<int> reservoir, CancellationToken cancellationToken)
|
||||
{
|
||||
/**
|
||||
* int M = 3; // 需要抽样的元素个数
|
||||
* int totalElements = 10; // 输入数据的总元素个数
|
||||
* var arr = new List<int>();
|
||||
*
|
||||
* for (int i = 1; i <= totalElements; i++)
|
||||
* {
|
||||
* arr.Add(i);
|
||||
* }
|
||||
*
|
||||
* ConcurrentBag<int> reservoir = new ConcurrentBag<int>();
|
||||
* Random random = new Random();
|
||||
*
|
||||
* var cancellationTokenSource = new CancellationTokenSource();
|
||||
* var cancellationToken = cancellationTokenSource.Token;
|
||||
*
|
||||
* ThreadPool.QueueUserWorkItem(state =>
|
||||
* ReservoirSampling(arr, M, reservoir, random, cancellationToken);
|
||||
* , null);
|
||||
*
|
||||
* // 停止抽样
|
||||
* cancellationTokenSource.Cancel();
|
||||
*/
|
||||
var random = new System.Random();
|
||||
|
||||
for(int i = select; i < arr.Count; ++i)
|
||||
{
|
||||
if(cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
int k = random.Next(i + 1); // 生成一个随机数 k,范围是 [0, i]
|
||||
if(k < select)
|
||||
{
|
||||
// 如果 k 小于 M,将 arr[k] 添加到抽样结果中
|
||||
reservoir.Add(arr[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user