組合せ

CombinationTest.lzh

順列は生成された数字群に順番がありますが、組合せは順番のない数字群です。 順列と同じように、スキップ機能付の組合せ生成クラスを用います。

組合せ生成は、基本的には次のようなクラスです。

public class Combination{
    private int N;
    private int R;
    public  int[] Index=null;
    private bool First=false;

    public Combination( int N, int R ){
        this.N=N;
        this.R=R;
        if( R>0 && R<=N ){
            Cmb=new int[R];
            Cmb[0]=0;
            for( int m=1; m<R; m++ ) Index[m]=Index[m-1]+1;
            First=true;
        }
    }
    public bool Successor(int skip=int.MaxValue){
        if(N<=0) return false;
        if(First){ First=false; return (Index!=null); }

        int k;
        if(Index[0]==N-R) return false;
        if(skip<R-1){
            for(k=skip; k>=0; k--){ if(Index[k]<=N-R) break; }
            if(k<0)  return false;
        }
        else{
            for(k=R-1; k>0 && Index[k]==N-R+k; --k);
        }

        ++Index[k];
        for(int j=k; j<R-1; ++j)  Index[j+1]=Index[j]+1;
        return true;
    }
}

Combinationは次のように使います。
次の組合せ生成の変更位置はダイナミックに変更できます。位置指定は0~(組合せサイズ-1)で、これ以外の場合または指定を省略したときはスキップ機能は働きません。

var cmb = new Combination (6,3);
int skip=4;
    while(cmb.Successor(skip) ){
    (評価処理)(次の組合せ生成の変更位置skipを設定))
}

テストプログラム(CombinationTest)

static void Main( string[ ] args ){
    for( int skip=0; skip<5; skip++ ){
        Combination cmb = new Combination(6,4);
        Console.WriteLine("\n ===== Combination(6,4) skip={0}",skip );
        while( cmb.Successor(skip) )  Console.WriteLine(cmb);
        Console.ReadKey();
    }
}

実行結果(左:組み合わせ生成結果 右:関数内部の作業データ)

===== Combination(6,4) skip=0
 0 1 2 3
 1 2 3 4
 2 3 4 5

 ===== Combination(6,4) skip=1
 0 1 2 3
 0 2 3 4
 0 3 4 5
 1 2 3 4
 1 3 4 5
 2 3 4 5

 ===== Combination(6,4) skip=2
 0 1 2 3
 0 1 3 4
 0 2 3 4
 0 3 4 5
 1 2 3 4
 1 3 4 5
 2 3 4 5
 
===== Combination(6,4) skip=3
 0 1 2 3
 0 1 2 4
 0 1 2 5
 0 1 3 4
 0 1 3 5
 0 1 4 5
 0 2 3 4
 0 2 3 5
 0 2 4 5
 0 3 4 5
 1 2 3 4
 1 2 3 5
 1 2 4 5
 1 3 4 5
 2 3 4 5

 ===== Combination(6,4) skip=4
 0 1 2 3
 0 1 2 4
 0 1 2 5
 0 1 3 4
 0 1 3 5
 0 1 4 5
 0 2 3 4
 0 2 3 5
 0 2 4 5
 0 3 4 5
 1 2 3 4
 1 2 3 5
 1 2 4 5
 1 3 4 5
 2 3 4 5

Top