2017-06-30 6 views
1

たとえば、配列[0,1,2,3,4]を持っていて、番号を含む繰り返しなしですべての3要素の組み合わせを見つけたいというような、繰り返しのない10個の要素の組み合わせをすべて探したいとします0 Iは、以下の結果を得る:0,1,2; 0,1,3; 0,1,4; 0,2,3; 0,2,4; 0,4,3;特定の数の繰り返しを伴わない組み合わせ

検索方法は、高速でなければならない - N全ての組み合わせを発見した後、濾過して、K = 10のための組合せを検索長すぎると、例えばある= 64がアウトのを151473214816組み合わせを与え、生成 - メモリ例外(16GB RAM、i7 7600U)

このメソッドは、長い間。

k = 2またはk = 3は、私は次のメソッドを使用する場合、たとえば、すべての組み合わせを検索するには:

public static IEnumerable<IEnumerable<T>> GetKCombs<T>(IEnumerable<T> list, int length) where T : IComparable 
{ 
    if (length == 1) 
    { 
     return list.Select(t => new T[] { t }); 
    } 
    else 
    { 
     return GetKCombs(list, length - 1).SelectMany(t => list.Where(o => o.CompareTo(t.Last()) > 0), (t1, t2) => t1.Concat(new T[] { t2 })); 
    } 
} 

はどのようにして、特定の番号またはどのようにそれは新しいはずが含まれているだけの組み合わせを選択するには、この方法を変更する必要がありますか?

おそらく、メソッドはすべての可能な組み合わせを検索し、特定の番号を持つものだけを(再帰的に)再作成するためにフィルタリングすべきではありませんが、そのようなメソッドを記述する方法や既存のものを変更する方法はわかりません。

誰かがこの問題を解決するのに役立つことができますか?

私はこの方法を使用
+1

私は、選択された要素/要素( '[0]' = '[1,2,3,4] 'を除く' [0,1,2,3,4] ( '[0]')と上記の定義された集合( '[1,2,3,4]')のすべてのNxの組み合わせを返す:この時点ではすべてが標準である –

+0

あなた1秒間に151,473,214,816の組み合わせのうちの100万を処理することができます(これはほとんどないと思われます)。それから、それらをすべて処理するにはおよそ2日間かかります。これはあまり実用的ではないようです... –

+0

"すべての組み合わせを見つけてからフィルタリングするのが長すぎます"実際には反対に行う必要がありますが、残りの組み合わせを合理的な数に減らすのに十分なフィルタリングが必要です –

答えて

0

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k) 
{ 
    return k == 0 ? new[] { new T[0] } : 
     elements.SelectMany((e, i) => 
     elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c))); 
} 

これは、特定のインスタンスとの組み合わせのみを返します:

public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k, T instance) 
{ 
    if(k == 0 || !elements.Contains(instance)) return new[] { new T[0] }; 
    return elements.Where(x => !Equals(x, instance)).Combinations(k - 1).Select(c => (new[] {instance}).Concat(c)); 
} 

考え方は単純です:あなたなしでリストからすべての組み合わせ(K-1の要素)を取得しますインスタンスを追加し、インスタンスを結果に追加します。

私は決してそのパフォーマンスをチェックしていません。結果を共有したい場合は、試してみてください。組み合わせの数は同じでなければなりませんが、私はこれらの方法で大きな違いはないと思います。

+0

あなたのメソッドはすべてのk要素の組み合わせを返しますが、すべてのk要素の組み合わせを返すメソッドが必要です。組み合わせの要素の1つがたとえば数字10の場合。 あなたの方法は私の方が速いと思いますが、 :( – xpasd

+0

私はあなたが必要とするべき第二の方法を追加しました。 –

関連する問題