多个列表中的最高分

时间:2018-05-27 17:52:27

标签: c# algorithm list threshold

我有一个包含KeyValuePair<int, double>的列表,按双精度排序,其中int代表 ID double代表该ID的分数。我想创建一个算法,它给出了ID的前k个,其中ID的总和最大化。现在,我知道如何做到这一点,但我不知道如何在c#中实现它。

因此,我们的想法是获取每个列表的第一个元素并计算阈值&#39;,该行的得分总和,即总和的最大值。然后我们查找该行中ID的所有分数总和,并将其放入缓冲区。然后我们移动到下一行并计算阈值和分数,如果缓冲区中的一个分数高于当前阈值,我们知道它应该在top-k中并将其放在那里然后继续我们有k值。我希望有人能指出我正确的方向。

一些示例数据: 列表中有两个列表如下:

{(1, 25), (2, 23), (3, 19), (4, 10), (5, 3)}, 
{(2, 24), (3, 20), (1, 15), (5, 10), (4, 3)}

在第一轮之后,我们的阈值为25+24 = 49,缓冲区由(1, 40)(2, 47)组成。我们移动到下一行并找到值(2, 23)(3, 20),因此阈值为43,我们将(3, 39)添加到缓冲区。我们在缓冲区中看到ID为2的元组的分数高于阈值,因此我们将其添加到Top-k。

这些列表最多包含100000 KeyValuePairs,而且只需要处理一些KeyValuePairs来查找top-k,而不是只计算每个元组的得分并取得前k个

1 个答案:

答案 0 :(得分:0)

如果您的意思是按Key总计一个键值对列表,其中得分为Value,那么您可以非常简单地使用Linq,例如获得前2名玩家得分:

var playerScores = new List<KeyValuePair<int, double>>() {
    new KeyValuePair<int, double>(1, 1.0),
    new KeyValuePair<int, double>(2, 20.0),
    new KeyValuePair<int, double>(3, 10.8),
    new KeyValuePair<int, double>(1, 15.2),
    new KeyValuePair<int, double>(2, 10.2),
    new KeyValuePair<int, double>(3, 8.4),
    new KeyValuePair<int, double>(1, 3),
    new KeyValuePair<int, double>(2, 6.6),
    new KeyValuePair<int, double>(3, 9.2),
};

var totalScores = playerScores
    .GroupBy(a => a.Key)
    .Select(g => new { id = g.Key, total = g.Sum(gk => gk.Value) })
    .OrderByDescending(x => x.total);

foreach (var player in totalScores.Take(2)) // find the top 2 scores
{
    Console.WriteLine($"player {player.id} scores {player.total}");
}

输出:

player 2 scores 36.8
player 3 scores 28.4