今回はタイトルのような関数を作ってみたいと思います。
0と1の組み合わせってなんやねんっていうと、例えば2個のもので考えるなら
こんな感じ。この組み合わせの総数はあるので、手作業で頑張るのは個数が大きくなってくるとしんどいです。
※5個の時点で32パターンあります。
そこで、関数化してみます。
目次
スポンサーリンク
アイデアの種
例えば、先ほどのを次のように縦に並べてみます。
これらの数列を左の項から順番に比べた時に、どの時点で各数列が異なると識別できるのか考えてみます。
例えば最初にあると
は初めの数字は同じ0で異なるものかどうかは識別出来ません、次に並ぶ数字を確認して初めて異なる数列であると判断できます。
アルゴリズムのアイデア
もう少し個数の多い例でも見てみます。例えば5個のケース。
[,1] [,2] [,3] [,4] [,5] [1,] 0 0 0 0 0 [2,] 0 0 0 0 1 [3,] 0 0 0 1 0 [4,] 0 0 0 1 1 [5,] 0 0 1 0 0 [6,] 0 0 1 0 1 [7,] 0 0 1 1 0 [8,] 0 0 1 1 1 [9,] 0 1 0 0 0 [10,] 0 1 0 0 1 [11,] 0 1 0 1 0 [12,] 0 1 0 1 1 [13,] 0 1 1 0 0 [14,] 0 1 1 0 1 [15,] 0 1 1 1 0 [16,] 0 1 1 1 1 [17,] 1 0 0 0 0 [18,] 1 0 0 0 1 [19,] 1 0 0 1 0 [20,] 1 0 0 1 1 [21,] 1 0 1 0 0 [22,] 1 0 1 0 1 [23,] 1 0 1 1 0 [24,] 1 0 1 1 1 [25,] 1 1 0 0 0 [26,] 1 1 0 0 1 [27,] 1 1 0 1 0 [28,] 1 1 0 1 1 [29,] 1 1 1 0 0 [30,] 1 1 1 0 1 [31,] 1 1 1 1 0 [32,] 1 1 1 1 1
個数は5なので、通りあります。組み合わせを考えれば自明ですが、一番初めの数字が0のパターンは
通り、一番初めの数字が1のパターンも同様に
通りあるはずです。
一番初めの数字が0のパターンだけ試しに抜き出してみます。
[,1] [,2] [,3] [,4] [,5] [1,] 0 0 0 0 0 [2,] 0 0 0 0 1 [3,] 0 0 0 1 0 [4,] 0 0 0 1 1 [5,] 0 0 1 0 0 [6,] 0 0 1 0 1 [7,] 0 0 1 1 0 [8,] 0 0 1 1 1 [9,] 0 1 0 0 0 [10,] 0 1 0 0 1 [11,] 0 1 0 1 0 [12,] 0 1 0 1 1 [13,] 0 1 1 0 0 [14,] 0 1 1 0 1 [15,] 0 1 1 1 0 [16,] 0 1 1 1 1
今度は一つ目の数字は皆同じなので二つ目の数字を見てみます。先ほどと同様に16パターンのうち、二つ目の数字が0であるパターンは個のはずです。
この操作を順々に繰り返していくと結局、総パターンの内、左から見ていった時にまでが同じ数列であるパターン数は
であると考えられます。
関数化
さて、今の手順を関数化してみることにします。
subsetfun=function(kosuu){ XX=matrix(,2^kosuu,kosuu) for(i in 1:kosuu){ CCC=t(rbind(rep(0,2^(kosuu-i)),rep(1,2^(kosuu-i)))) XX[,i]=rep(CCC,2^(i-1)) } return(XX) }
試しに、個数=6で出力してみます。
> subsetfun(6) [,1] [,2] [,3] [,4] [,5] [,6] [1,] 0 0 0 0 0 0 [2,] 0 0 0 0 0 1 [3,] 0 0 0 0 1 0 [4,] 0 0 0 0 1 1 [5,] 0 0 0 1 0 0 [6,] 0 0 0 1 0 1 [7,] 0 0 0 1 1 0 [8,] 0 0 0 1 1 1 [9,] 0 0 1 0 0 0 [10,] 0 0 1 0 0 1 [11,] 0 0 1 0 1 0 [12,] 0 0 1 0 1 1 [13,] 0 0 1 1 0 0 [14,] 0 0 1 1 0 1 [15,] 0 0 1 1 1 0 [16,] 0 0 1 1 1 1 [17,] 0 1 0 0 0 0 [18,] 0 1 0 0 0 1 [19,] 0 1 0 0 1 0 [20,] 0 1 0 0 1 1 [21,] 0 1 0 1 0 0 [22,] 0 1 0 1 0 1 [23,] 0 1 0 1 1 0 [24,] 0 1 0 1 1 1 [25,] 0 1 1 0 0 0 [26,] 0 1 1 0 0 1 [27,] 0 1 1 0 1 0 [28,] 0 1 1 0 1 1 [29,] 0 1 1 1 0 0 [30,] 0 1 1 1 0 1 [31,] 0 1 1 1 1 0 [32,] 0 1 1 1 1 1 [33,] 1 0 0 0 0 0 [34,] 1 0 0 0 0 1 [35,] 1 0 0 0 1 0 [36,] 1 0 0 0 1 1 [37,] 1 0 0 1 0 0 [38,] 1 0 0 1 0 1 [39,] 1 0 0 1 1 0 [40,] 1 0 0 1 1 1 [41,] 1 0 1 0 0 0 [42,] 1 0 1 0 0 1 [43,] 1 0 1 0 1 0 [44,] 1 0 1 0 1 1 [45,] 1 0 1 1 0 0 [46,] 1 0 1 1 0 1 [47,] 1 0 1 1 1 0 [48,] 1 0 1 1 1 1 [49,] 1 1 0 0 0 0 [50,] 1 1 0 0 0 1 [51,] 1 1 0 0 1 0 [52,] 1 1 0 0 1 1 [53,] 1 1 0 1 0 0 [54,] 1 1 0 1 0 1 [55,] 1 1 0 1 1 0 [56,] 1 1 0 1 1 1 [57,] 1 1 1 0 0 0 [58,] 1 1 1 0 0 1 [59,] 1 1 1 0 1 0 [60,] 1 1 1 0 1 1 [61,] 1 1 1 1 0 0 [62,] 1 1 1 1 0 1 [63,] 1 1 1 1 1 0 [64,] 1 1 1 1 1 1
うまくいっていますね。
コメント
この関数、なんで作ろうかと思ったかというと、線形回帰の変数選択の自動化をしたかったから書きました。次回にでも変数選択の自動化関数についても書いてみたいと思います。
ちなみにyahoo知恵袋にてこんな質問が落ちていました。
4桁かつ、0と1の組み合わせ - 0と1からなる4桁の数字の組み合わせはどれく... - Yahoo!知恵袋
この手の質問もこの関数ならすぐに視覚的に見せることが出来ますね。