3

nを計算してkを選択し、辞書式順序ですべての可能な組み合わせを生成するこのc#クラスがあります。また、各組み合わせの注文番号を返すこともできます。たとえば、[1,2,3,4,5]を渡すと、nがk(30,5)を選択すると、1が返され、[26,27,28,29,30]の場合は142506が返されます。 。

部分的な組み合わせを含むすべての注文番号を返す方法はありますか?したがって、[1,2,3,4]を渡すと、次のようになります:1,2,3、...25,26。

1: [1,2,3,4,5]
2: [1,2,3,4,6]
3: [1,2,3,4,7]
...
25: [1,2,3,4,29]
26: [1,2,3,4,30]

宝くじ抽選にこれが必要です。各チケットにその組み合わせの注文番号を付けたいので、5つのボールのそれぞれが描かれるときに、勝者候補の合計を表示する必要があります。現在、各チケットには実際の組み合わせがあり、部分的な勝者を取得するためにクエリを実行しますが、このプロセスを最適化したいと思います。

4

2 に答える 2

3

必要なのは、組み合わせ[a、b、c、d、e]に対して、その組み合わせの注文番号を返す関数です。次に、組み合わせセット(可能な数のセットからすでに選択されている数を引いたもの)を選択し(まだ選択していない数)、各組み合わせにすでに選択されている数を追加し、各組み合わせを並べ替えて、それを使用できます。注文番号を取得する関数。

編集:これは役立つかもしれません:saliu.com/bbs/messages/348.html

EDIT2:そして答えはここにあります:組み合わせが与えられたときにインデックス(辞書式順序)を計算する方法

EDIT3:私はこれのためにいくつかのC#コードを突き刺しました:

private IEnumerable<int[]> CombinationsFor(int n, int k);
private int CombinationsCount(int n, int k);

private int IndexFor(int n, int[] combination)
{
    int k = combination.Count();
    int ret = 0;

    int j = 0;
    for (int i = 0; i < k; i++)
    {
        for (j++; j < combination[i]; j++)
        {
            ret += CombinationsCount(n - j, k - i - 1);
        }
    }

    return ret;
}

private IEnumerable<int> PossibleCombinations(int n, int k, int[] picked)
{
    int m = picked.Count();

    int[] reverseMapping = Enumerable.Range(0, n)
        .Where(i=>!picked.Contains(i))
        .ToArray();

    return CombinationsFor(n-m, k-m)
        .Select(c => c
            .Select(x=>reverseMapping[x])
            .Concat(picked)
            .OrderBy(x=>x)
            .ToArray()
        )
        .Select(c => IndexFor(n, c));
}
于 2012-06-27T18:19:01.443 に答える
3

必要な組み合わせ(n-d) choose (k-d)d、固定ドローの数です。

それらを生成するとき、それらは正しい番号を持ちません(それらはdあなたが望むものの代わりに最後の番号をスキップします)が、あなたのサブリストの逆順マッピングを使用してあなたの組み合わせを言い換えるだけです:

(pseudo-python-codeでは、これはC#とはまったく関係がないため)

listing = [1, 2, ..., 30]
partial = [4, 7, 25]
draw_size = 5
remaining = listing - partial
reverse_order_mapping = [(index, item) in remaining.items_and_indexes]

n = listing.size  // 30
k = draw_size     // 5
d = partial.size  // 3

for comb in ((n-d) choose (k-d))
  actual_comb = comb.map(reverse_order_mapping)
  print actual_comb
end

次に、結果の組み合わせを使用して関数を呼び出します(必要に応じて並べ替えた後)。

于 2012-06-27T18:23:52.440 に答える