【发布时间】:2017-01-17 12:05:07
【问题描述】:
使用 C#/Asp.Net。
我正在努力实现以下目标:
我有一个报价清单 - 有时有多个产品价格相同。
此外,有些结果是附属(赞助)的,因此我们也需要优先考虑这些结果。
这是调用的方法:
public IEnumerable<PriceQuote> BestQuote(int take = 0)
{
var q = Quotes.Where(x => x.TotalRepayable == MinPrice)
.Shuffle()
.OrderByDescending(x => x.ProductDetail.Product.IsSponsored);
return take == 0 ? q : q.Take(take);
}
代码选择具有最低可用价格的商品。然后的想法是将它们按完全随机的顺序排序,然后按赞助标志降序(赞助 = 1 而不是 0)再次排序,然后取所需的结果。
我首先将它们洗牌以获得随机顺序 - 从随机列表中我想首先获取赞助项目 - 然后在必要时用非赞助项目填充空间。理论上,赞助商和非赞助商每次都会随机排列。
Example in natural order:
product1 (not sponsored)
product2 (sponsored)
product3 (not sponsored)
product4 (sponsored)
product5 (not sponsored)
product6 (sponsored)
Shuffle randomly:
product3 (not sponsored)
product1 (not sponsored)
product2 (sponsored)
product6 (sponsored)
product5 (not sponsored)
product4 (sponsored)
Order by sponsored first keeping randomness:
product2 (sponsored) <-- pick these first
product6 (sponsored)
product4 (sponsored)
product3 (not sponsored)
product1 (not sponsored)
product5 (not sponsored)
这是我的随机播放方法:
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this)
{
if (@this.Count() <= 1) return @this;
return @this.ShuffleIterator(new Random());
}
static IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source, Random rng)
{
var buffer = source.ToList();
for (int i = 0; i < buffer.Count; i++)
{
int j = rng.Next(i, buffer.Count);
yield return buffer[j];
buffer[j] = buffer[i];
}
}
我遇到的问题是,当我为不同的报价连续多次调用 BestQuote 方法时,我往往会得到相同的结果。例如,我的列表包含 6 种产品,我每次选择第一个结果进行 3 次调用,很可能所有 3 次调用的顺序相同。并非总是如此 - 存在一些差异,但匹配的比不匹配的多。
Call 1: product2 <--
Call 2: product2 <--
Call 3: product2 <-- this is a common scenario where there seems to be no randomness
【问题讨论】:
-
当您使用单个静态 Random 实例时会发生什么?没有参数
new Random()使用当前时间作为种子,如果你将它们实例化在一起,你会得到相同的时间 = 相同的种子 = 相同的值。 -
首先,检查this almost-duplicate question 以获得正确的随机播放实现。其次,Random 返回一个 缩放 到您请求的范围的浮点数。如果您的列表包含 4 个项目,则有 25% 的机会下一个双精度数将缩放为相同的整数。如果您请求一个 large 整数然后取其模数对计数,您会得到更好的结果,例如
rng.Next(int.MaxValue)%buffer.Count -
Random() 使用基于时间的种子。如果你快速调用你的方法,你会得到同样的结果。您应该使用静态 Random() 类。
-
@PanagiotisKanavos 在 NET Core 中不再适用。仍然是 applies 到完整的 .NET Framework。