gpt4 book ai didi

c# - 如何从总计为 y 的唯一小数列表中获取随机 x 位数的小数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:52:31 26 4
gpt4 key购买 nike

假设我有一个按值排列的 1000 左右唯一小数的排序列表。

List<decimal> decList

如何从总计为 y 的唯一小数列表中随机获取 x 位数的小数?

private List<decimal> getWinningValues(int xNumberToGet, decimal yTotalValue)
{

}

有什么办法可以避免处理时间过长?到目前为止,我的想法是从池中获取 xNumberToGet 随机数。类似于(从列表中随机选择的好方法)

foreach (decimal d in decList.OrderBy(x => randomInstance.Next())Take(xNumberToGet))
{

}

然后我可能会检查这些总数,如果总数较少,我可能会慢慢地将数字向上移动(到下一个可用数字)。如果总数更多,我可能会将数字向下移动。我现在仍然确定如何实现,或者是否有更好的设计可供使用。任何帮助将非常感激。

最佳答案

好的,从我从 this answer 得到的一个小扩展开始,

public static IEnumerable<IEnumerable<T>> Combinations<T>(
this IEnumerable<T> source,
int k)
{
if (k == 0)
{
return new[] { Enumerable.Empty<T>() };
}

return source.SelectMany((e, i) =>
source.Skip(i + 1).Combinations(k - 1)
.Select(c => (new[] { e }).Concat(c)));
}

这为您提供了一种非常有效的方法,可以从给定的 IEnumerable 中生成具有 k 成员的所有组合,而无需重复。您可以在实现中充分利用这一点。

请记住,如果 IEnumerablek 足够大,这可能需要一些时间,即比您拥有的时间长得多。所以,我修改了你的函数以获取 CancellationToken。 .

private static IEnumerable<decimal> GetWinningValues(
IEnumerable<decimal> allValues,
int numberToGet,
decimal targetValue,
CancellationToken canceller)
{
IList<decimal> currentBest = null;
var currentBestGap = decimal.MaxValue;
var locker = new object();

allValues.Combinations(numberToGet)
.AsParallel()
.WithCancellation(canceller)
.TakeWhile(c => currentBestGap != decimal.Zero)
.ForAll(c =>
{
var gap = Math.Abs(c.Sum() - targetValue);
if (gap < currentBestGap)
{
lock (locker)
{
currentBestGap = gap;
currentBest = c.ToList();
}
}
}

return currentBest;
}

我有一个想法,当总和必须超过目标时,您可以对初始列表进行排序并在某个点停止迭代组合。经过一番考虑,确定该点并非易事,而且检查的成本可能超过 yield 。这种好处必须与目标值的某些函数和集合的平均值相平衡。

我仍然认为可以进一步优化,但我也认为这项工作已经完成,我只需要 look it up in the right place .

关于c# - 如何从总计为 y 的唯一小数列表中获取随机 x 位数的小数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12854936/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com