这是一个关于实体框架的问题,一直困扰着我。
我有一张名为奖品的桌子,有不同的奖品。一些有较高的,一些有较低的货币价值。它的简单表示就是这样:
+----+---------+--------+
| id | name | weight |
+----+---------+--------+
| 1 | Prize 1 | 80 |
| 2 | Prize 2 | 15 |
| 3 | Prize 3 | 5 |
+----+---------+--------+
重量是这种情况,我希望这个项目随机选择。
我一次选择一个随机奖品:
var prize = db.Prizes.OrderBy(r => Guid.NewGuid()).Take(1).First();
我想要做的是使用权重来确定随机项目返回的可能性,因此Prize 1
将返回80%的时间,Prize 2
15%,依此类推。< / p>
我认为这样做的一种方法是将数据库上的奖金与重量一样多。与Prize 1
相比,具有80次Prize 3
的那种方式返回的可能性更高,但这不一定完全正确。
必须有更好的方法来做到这一点,所以我想知道你是否可以帮助我解决这个问题。
提前致谢
答案 0 :(得分:0)
通常我不会在数据库中这样做,而是使用代码来解决问题。 在你的情况下,我会生成1到100之间的随机数。如果生成的数字在1到80之间,那么第一个获胜,如果它在81到95之间,那么第二个获胜,如果在96到100之间最后一场胜利。 因为随机数可以是从1到100的任意数字,每个数字有1%的机会被击中,那么你可以通过给出随机数落入的范围来管理获胜机会。 希望这可以帮助。 亨利
答案 1 :(得分:0)
这可以通过为三个(通常是n个)项目创建垃圾箱,然后选择要在其中一个垃圾箱中放置的选定随机数来完成。
可能有一个统计库可以为你做这件事,即按比例从n个箱子中选择一个箱子。
可以像下面这样实施一个不限制三个奖品/重量的解决方案:
//All Prizes in the Database
var allRows = db.Prizes.ToList();
//All Weight Values
var weights = db.Prizes.Select(p => new { p.Weight });
//Sum of Weights
var weightsSum = weights.AsEnumerable().Sum(w => w.Weight);
//Construct Bins e.g. [0, 80, 95, 100]
//Three Bins are: (0-80],(80-95],(95-100]
int[] bins = new int[weights.Count() + 1];
int start = 0;
bins[start] = 0;
foreach (var weight in weights) {
start++;
bins[start] = bins[start - 1] + weight.Weight;
}
//Generate a random number between 1 and weightsSum (inclusive)
Random rnd = new Random();
int selection = rnd.Next(1, weightsSum + 1);
//Assign random number to the bin
int chosenBin = 0;
for (chosenBin = 0; chosenBin < bins.Length; chosenBin++)
{
if (bins[chosenBin] < selection && selection <= bins[chosenBin + 1])
{
break;
}
}
//Announce the Prize
Console.WriteLine("You have won: " + allRows.ElementAt(chosenBin));