C# 博弈赢家之间利润的对数分布
我有一个give,当它结束时,有一个球员和他们的分数表。 另一方面,我有一大笔钱要分给这些获奖者。我正在寻找一个SQL查询或一段C代码来实现这一点 降序排序表如下所示:C# 博弈赢家之间利润的对数分布,c#,sql,math,polynomial-math,logarithm,C#,Sql,Math,Polynomial Math,Logarithm,我有一个give,当它结束时,有一个球员和他们的分数表。 另一方面,我有一大笔钱要分给这些获奖者。我正在寻找一个SQL查询或一段C代码来实现这一点 降序排序表如下所示: UserId | Name | Score | Position | % of winnings | abs. winnings $ 00579 | John | 754 | 1 | ? | 500 $ 98983 | Sam | 733 | 2 | ?
UserId | Name | Score | Position | % of winnings | abs. winnings $
00579 | John | 754 | 1 | ? | 500 $
98983 | Sam | 733 | 2 | ? | ?
29837 | Rick | 654 | 3 | ? | ? <- there are 2 3rd places
21123 | Hank | 654 | 3 | ? | ? <- there are 2 3rd places
99821 | Buck | 521 | 5 | ? | ? <- there is no 4th, because of the 2 3rd places
92831 | Joe | 439 | 6 | ? | ? <- there are 2 6rd places
99281 | Jack | 439 | 6 | ? | ? <- there are 2 6rd places
12345 | Hal | 412 | 8 | ? | ?
98112 | Mick | 381 | 9 | ? | ?
and so on, until position 50
98484 | Sue | 142 | 50 | ? | 5 $
那么这个怎么样
Select userid, log(score),
10000 * log(score) /
(Select Sum(log(score))
From TableName
Where score >=
(Select Min(score)
from (Select top 50 score
From TableName
Order By score desc) z))
From TableName
Order By score desc
自1994年以来我就没有做过SQL,但我喜欢C:-)。以下内容可能适用,请根据需要调整
distributewinput.distributewinput(…)
的参数:
private class DistributeWinPot {
private static double[] GetWinAmounts(int[] psns, double TotWinAmounts, double HighWeight, double LowWeight) {
double[] retval = new double[psns.Length];
double fac = -Math.Log(HighWeight / LowWeight) / (psns.Length - 1), sum = 0;
for (int i = 0; i < psns.Length; i++) {
sum += retval[i] = (i == 0 || psns[i] > psns[i - 1] ? HighWeight * Math.Exp(fac * (i - 1)) : retval[i - 1]);
}
double scaling = TotWinAmounts / sum;
for (int i = 0; i < psns.Length; i++) {
retval[i] *= scaling;
}
return retval;
}
public static void main(string[] args) {
// set up dummy data, positions in an int array
int[] psns = new int[50];
for (int i = 0; i < psns.Length; i++) {
psns[i] = i+1;
}
psns[3] = 3;
psns[6] = 6;
double[] WinAmounts = GetWinAmounts(psns, 10000, 500, 5);
for (int i = 0; i < psns.Length; i++) {
System.Diagnostics.Trace.WriteLine((i + 1) + "," + psns[i] + "," + string.Format("{0:F2}", WinAmounts[i]));
}
}
}
我运行了此查询,但结果与我搜索的结果不太一样。我在示例中添加了更多内容。比如第一名和第五十名的绝对金额。固定为500和5。看起来很有趣。但是,我没有得到高权重,你输入500,但最高赢金额是894.70??是吗?是的,我有500和5,正如你在问题中建议的那样。但是,它需要使权重总和达到10000。因此它必须缩放初始结果,这就是
for
的第二个循环在DistributeWinPot.DistributeWinPot(…)
中所做的。有道理吗?是的,有道理。我现在正在玩输入值的游戏,我看到当我提供一个总赢金额,这将很容易适应50个赢家,我总是得到一个更高的金额为我的数字1和数字2总是得到最大金额。这对我来说没什么意义。我不明白你的疑问。你能举个例子吗?你有没有办法让我的支付曲线变得更陡或更陡?假设平手赚的钱相同,这是不可能的。这个问题过于局限。例如,如果第一名是49路平手,你必须支付24505美元。你可能永远不会有一个49路平局,但你应该明确你关心的可能性和你不关心的可能性。
private class DistributeWinPot {
private static double[] GetWinAmounts(int[] psns, double TotWinAmounts, double HighWeight, double LowWeight) {
double[] retval = new double[psns.Length];
double fac = -Math.Log(HighWeight / LowWeight) / (psns.Length - 1), sum = 0;
for (int i = 0; i < psns.Length; i++) {
sum += retval[i] = (i == 0 || psns[i] > psns[i - 1] ? HighWeight * Math.Exp(fac * (i - 1)) : retval[i - 1]);
}
double scaling = TotWinAmounts / sum;
for (int i = 0; i < psns.Length; i++) {
retval[i] *= scaling;
}
return retval;
}
public static void main(string[] args) {
// set up dummy data, positions in an int array
int[] psns = new int[50];
for (int i = 0; i < psns.Length; i++) {
psns[i] = i+1;
}
psns[3] = 3;
psns[6] = 6;
double[] WinAmounts = GetWinAmounts(psns, 10000, 500, 5);
for (int i = 0; i < psns.Length; i++) {
System.Diagnostics.Trace.WriteLine((i + 1) + "," + psns[i] + "," + string.Format("{0:F2}", WinAmounts[i]));
}
}
}
1,1,894.70
2,2,814.44
3,3,741.38
4,3,741.38
5,5,614.34
6,6,559.24
7,6,559.24
8,8,463.41
9,9,421.84
10,10,384.00
11,11,349.55
12,12,318.20
13,13,289.65
14,14,263.67
15,15,240.02
16,16,218.49
17,17,198.89
18,18,181.05
19,19,164.81
20,20,150.03
21,21,136.57
22,22,124.32
23,23,113.17
24,24,103.02
25,25,93.77
26,26,85.36
27,27,77.71
28,28,70.74
29,29,64.39
30,30,58.61
31,31,53.36
32,32,48.57
33,33,44.21
34,34,40.25
35,35,36.64
36,36,33.35
37,37,30.36
38,38,27.64
39,39,25.16
40,40,22.90
41,41,20.85
42,42,18.98
43,43,17.27
44,44,15.72
45,45,14.31
46,46,13.03
47,47,11.86
48,48,10.80
49,49,9.83
50,50,8.95