2015-12-08 69 views
0

下面是一个关于实体框架的问题,它一直在困扰着我。不同权值的随机值

我有一个称为奖品的表,有不同的奖品。一些货币价值较高,一些货币价值较低。一个简单的表示将是这样的:

+----+---------+--------+ 
| 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%等等。

我认为这样做的一种方式是通过在数据库上获得与体重相同的奖金。与Prize 3相比,拥有80次Prize 1的回报率更高,但这并不一定准确。

必须有更好的方法来做到这一点,所以我想知道你是否可以帮我解决这个问题。

在此先感谢

回答

0

通常我不会在数据库中做到这一点,而是用代码来解决这个问题。 在你的情况下,我会在1到100之间产生一个随机数。如果产生的数字在1到80之间,那么第一个赢,如果它在81到95之间,那么第二个赢,如果在96到100之间,赢得。 由于随机数可以是从1到100的任意数字,每个数字有1%的机会被击中,那么你可以通过给出随机数落入的范围来管理获胜机会。 希望这有助于。 Henry

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));