• 締切済み

すべての組合せをシートに出力したい

a1~a10を1以上5以下の整数とするとき、 a1+a2+a3+a4+a5+a6+a7+a8+a9+a10=20 となるような組み合わせは、 (5,5,3,1,1,1,1,1,1,1)→10!/(2!*7!) =360通り (5,5,2,2,1,1,1,1,1,1)→10!/(2!*2!*6!)=1260通り (5,4,4,1,1,1,1,1,1,1)→10!/(2!*7!) =360通り (5,4,3,2,1,1,1,1,1,1)→10!/(6!) =5040通り (5,4,2,2,2,1,1,1,1,1)→10!/(3!*5!) =5040通り (5,3,3,3,1,1,1,1,1,1)→10!/(3!*6!) =840通り (5,3,3,2,2,1,1,1,1,1)→10!/(2!*2!*5!)=7560通り (5,3,2,2,2,2,1,1,1,1)→10!/(4!*4!) =6300通り (5,2,2,2,2,2,2,1,1,1)→10!/(6!*3!) =840通り (4,4,4,2,1,1,1,1,1,1)→10!/(3!*6!) =840通り (4,4,3,3,1,1,1,1,1,1)→10!/(2!*2!*6!)=1260通り (4,4,3,2,2,1,1,1,1,1)→10!/(2!*2!*5!)=7560通り (4,4,2,2,2,2,1,1,1,1)→10!/(2!*4!*4!)=3150通り (4,3,2,2,2,2,2,1,1,1)→10!/(2!*7!) =360通り (4,2,2,2,2,2,2,2,1,1)→10!/(2!*7!) =360通り (3,2,2,2,2,2,2,2,2,1)→10!/(8!) =90通り (2,2,2,2,2,2,2,2,2,2)→10!/(10!) =1通り で合計41,221通りだと思います。 ごの、41,221通りの組合せを、エクセルシートに 41,221行20列の範囲に漏れなく出力したいのですが、 VBAで上手いテクニックがあれば教えてください。 よろしくお願いいたします。

みんなの回答

  • warumx
  • ベストアンサー率0% (0/9)
回答No.4

なんらかの方法で全ての組合せが得られたとして、その後どのように その大量のデータを使うのでしょうか。そちらの方が心配です。 目的にもよりますが通常は全ての組合せが必要なケースは少ないと 思います。 最終目的を書かれれば皆さんのアドバイスも的確になるでしょう。

すると、全ての回答が全文表示されます。
  • layy
  • ベストアンサー率23% (292/1222)
回答No.3

上手いって何なんでしょうか。観点は速度、保守、汎用性、いろいろあります。 全体の組み合わせから不要なパターンを除く DO-LOOPやIF 各桁の必要な組み合わせパターンの積み重ね FORーNEXT多重 のどちらか。 5進数の考え方、組み合わせ数の求め方、n!は四則演算式でどうなるか、等を学習すればいいのでは?。 セルを操作しながら、ならOFFSETとか。 機能要件が明確ですしセル操作の類の命令書くだけでは?。あふれあれば5分割すればいい。

すると、全ての回答が全文表示されます。
  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.2

(4,3,2,2,2,2,2,1,1,1)の計算が間違っているし、 (4,3,3,3,2,1,1,1,1,1)や(3,3,3,3,3,1,1,1,1,1)などの組み合わせの漏れがありますね。 合計は72,403通りです。 下記のコードでできますが、Excel2007以降でないと行数の制限をオーバーしてしまいます。 Excel2003で実行するなら、シートを分けるなりして分割すれば可能でしょう。 Sub Test() Cells.Select Selection.ClearContents Range("A1").Select n0 = 0 n = 1 For i = 1 To 7 Cells(n, i) = 1 Next Cells(n, 8) = 3 Cells(n, 9) = 5 Cells(n, 10) = 5 Do IsOK = (Cells(n, 10) > 1) k = 9 Do While k > 0 If Cells(n, k) < 5 And IsOK Then n = n + 1 p = 0 For i = 1 To 10 If i < k Then Cells(n, i) = Cells(n - 1, i) ElseIf i = k Then Cells(n, i) = Cells(n - 1, i) + 1 ElseIf 20 - p - 5 * (10 - i) < 2 Then Cells(n, i) = 1 Else Cells(n, i) = 20 - p - 5 * (10 - i) End If p = p + Cells(n, i) Next Exit Do End If IsOK = (IsOK Or (Cells(n, k) > 1)) k = k - 1 Loop Loop While k > 0 End Sub

すると、全ての回答が全文表示されます。
  • imogasi
  • ベストアンサー率27% (4737/17070)
回答No.1

こんな趣味みたいな課題に付き合いたくないが、 プログラムで、初歩的にやるなら、ForNextループを10重にネスト(For a1=1 to 5,For a2=1 to 5・・・Next a1、Next a2・・・) にすればできるはず。 組み合わせの問題は手作業より計算が速いと言うだけで、良いアルゴリズムは無いのではないか。 近似値でよいタイプの値の算出は、色々とXX法がありうるが。 ーー もっとスマートな方法は(多分無いと思うが)数学のカテゴリにするものだよ。 そういうアイデアは並みの文系のプログラマには(VBAの経験は相当あっても)聞いても判らないだろう。

すると、全ての回答が全文表示されます。

関連するQ&A