2

我正在研究如何使用加权值有效地对列表进行排序。

每个项目都有一个 ID、名称和文件路径。每个项目还有一个值列表,这些值分配了一个百分比,显示它们与每个值的相关程度。

我需要对列表进行排序,以便列表顶端的项目是与当前参数最相关的项目。

可以说,

项目一:

  • A:50,B:30,C:20,D:10
  • X:50,Z:20

项目二:

  • A:100, B:0, C:0, D:0
  • X:0, Z:100

我的参数是 A 和 Z。显然,项目二应该在我的列表顶部,因为它是最相关的项目。但是我将如何实施呢?

奖励:能够进行轻微的随机化也很好,我不想每次都得到最终的相关项目。

谢谢

4

2 回答 2

2

假设你知道你的权重函数,你可以使用 Linq to Objects:

var sorted = (from o in myList orderby o.SortingValue select o).ToList();

在此示例中,SortingValue它将是对象上的一个属性,该属性封装了您问题中的属性并将实现您的算法。

SortingValue 的示例算法:

您可以使用字典来保存相关百分比

然后,您的“当前参数”可以用作字典的键以获得相关权重:

Dictionary<string, double> weightDictionary = // Load somehow

double SortingValue
{
    get {
        double sortingValue;

        foreach(string currentParameter in currentParameters)
        {
            sortingValue += weightDictionary[currentParameter];
        }

        // You could use Math.Random to get a number between say -0.1 and -.1.  
        // Multiply sortingValue by that random number.
        return sortingValue;
    }
}
于 2012-04-14T01:37:12.020 回答
0

很久以前,我为此目的创建了一个扩展方法。我刚刚再次遇到了对它的需求:

public static IOrderedEnumerable<TSource> OrderByWeight<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, int> weighting) where TKey : IComparable
{
    Dictionary<TSource, int> order = new Dictionary<TSource, int>();
    foreach (TSource item in source)
    {
        if (!order.ContainsKey(item)) order.Add(item, weighting(keySelector(item)));
    }
    return source.OrderBy(s => order[s]);
}

你可以像这样使用它:

var data = dt.Select(g => new
{
    Season = g.season,
    AverageTemp = g.temp
}).OrderByWeight(a => a.Season, x =>
{
    if (x == "WINTER") return 1;
    if (x == "SPRING") return 2;
    if (x == "SUMMER") return 3;
    if (x == "AUTUMN") return 4;
    return 99;
});

来源:来自我的旧博客

于 2015-01-29T11:18:05.383 回答