2

加重値を使用してリストを効果的にソートする方法を探しています。

各アイテムには、ID、名前、およびファイルパスがあります。各アイテムには、パーセンテージが割り当てられた値のリストもあり、各値との関連性を示しています。

リストの一番上にあるアイテムが現在のパラメーターに最も関連するアイテムになるように、リストを並べ替える必要があります。

まあ言ってみれば、

項目 1:

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

項目 2:

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

私のパラメータは A と Z です。最も関連性の高いアイテムであるため、明らかにアイテム 2 がリストの一番上にあるはずです。しかし、これを実装するにはどうすればよいでしょうか。

おまけ: わずかなランダム化もできるといいのですが、毎回決定的な関連アイテムが提供されるのは望ましくありません。

ありがとう

4

2 に答える 2

2

重み付け関数を知っていると仮定すると、Linq to Objects を使用できます。

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

この例でSortingValueは、質問の属性をカプセル化し、アルゴリズムを実装するオブジェクトのプロパティになります。

SortingValue のサンプル アルゴリズム:

Dictionary を使用して関連性パーセンテージを保持できます

次に、「現在のパラメーター」をディクショナリのキーとして使用して、関連する重みを取得できます。

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 に答える