• ベストアンサー

数値の組み合わせを求める方法

数値の組み合わせを求めるのによい方法はありませんか。 具体例を書きますのでよろしくお願いします。 2,3,5,8の4個の数値があります。 この数値のいずれかを足して10になる組み合わせを 求めたい。 この場合の答えは、 2+3+5=10または2+8=10から、 2,3,5の組み合わせ、または2,8の組み合わせ となります。 また、上の場合で、足して11になる数値の組み合わ せは、3,8の組み合わせのみです。 これらは、簡単に求められますが、数値が多くなって くると手で計算していては、ものすごく時間がかかって しまいます。 エクセルを使って、ササーッと求める方法があったら 教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

プログラムの書き方は、あまり自信ないですけど、 一例として作って見ました。 VBAが分かる様なので、考え方が分かれば私の作り方より きれいな書き方が出来るのではないかと思います。 標準モジュールに下記のプログラムを貼り付けて [Sheet1]のA列に数値を入力し、      B1セルに求めたい数値を入力し Testを実行してください [Sheet1]のC列,D列・・・に該当する組み合わせを表示します。 Sub test()   Dim ws As Worksheet   Dim tbl As Variant   Dim ans As Long   Set ws = Worksheets("Sheet1")   '対象となる数値群   tbl = ws.Range(ws.Range("A1"), ws.Cells(ws.Rows.Count, "A").End(xlUp)).Value   '求める数値   ans = ws.Range("B1")   '表示位置クリア   ws.Range("C:Z").Clear   MsgBox Anser(1, 0, ws, 1, 3, tbl, ans) & "個の組み合わせがありました" End Sub 'srow:検索を始める行 , wtotal:現在の合計 'ws:表示するシート,wrow:表示する行 , wcolumn:表示する列 'wtbl:対象となる数値群 , wans:求める数値 '戻り値:組み合わせの個数 Function Anser(ByVal srow As Long, ByVal wtotal As Long, ByVal ws As Worksheet, ByVal wrow As Long, ByVal wcolumn As Integer, ByVal wtbl As Variant, ByVal wans As Long) As Long   Dim i As Long   Dim wcnt As Long   Dim wtl As Long   Anser = 0   For i = srow To UBound(wtbl, 1)     wtl = wtotal + wtbl(i, 1)     If (wtl = wans) Then '求める数値と同じ       ws.Cells(wrow, wcolumn) = wtbl(i, 1)       Anser = Anser + 1       wrow = wrow + 1     ElseIf (wtl < wans) Then '求める数値より少ない       wcnt = Anser(i + 1, wtl, ws, wrow, wcolumn + 1, wtbl, wans)       If (wcnt > 0) Then '求める数値になる組み合わせがある         For j = 1 To wcnt           ws.Cells(wrow, wcolumn) = wtbl(i, 1)           wrow = wrow + 1         Next j         Anser = Anser + wcnt       End If     'Else 'ソートされている場合コメントをはずす     ' Exit For'ソートされている場合コメントをはずす     End If   Next i End Function A列の数値がソートされていれば、最後のコメント(')をはずしてください わからなければ、補足してください。 (テストを少数データでしか試してませんので、  バグがあったらそちらも補足してください)

nayaminosuke
質問者

お礼

taisuke555さんのVBA動かしてみました。 たちまち、答えが出て感動ものです。 プログラムの内容は、合計値と数値のセル範囲を取得して、セル範囲の数値を順番に足していって、合計値と合うたびに、表示位置もずらして、でもって組み合わせの個数もカウントしていくということのようですが、それをプログラムしてしまうところが、凄いです。私などとてもとてもできそうにありません。でもいつかはという気持ちです。本当にどうもありがとうございました。

nayaminosuke
質問者

補足

早速ありがとうございます。 私のVBA力は、事務処理中心で手作業での反復の自動化が主なので、書いてくださったプログラムには目がくらみました。読んで、考えて、テストして、また、ご連絡します。それまで、すこし待ってください。

その他の回答 (3)

  • nishi6
  • ベストアンサー率67% (869/1280)
回答No.4

2、3、5、8の場合の例です。 B1、C1、D1、E1に使用する数 2、3、5、8を入力します。 F1に指定する数値を入力します。 数値の組み合わせの種類は=2^4-1=15 なので A2~A16に1から15の数値を入力します。(2^4の4は使う数字の個数です) B2に =INT(A2/2^3) C2に =INT(MOD(A2,2^3)/2^2) D2に =INT(MOD(A2,2^2)/2^1) E2に =INT(MOD(A2,2^1)/2^0) F2に =IF(SUMPRODUCT($B$1:$E$1,B2:E2)=F$1,"OK","") とします。3行目から16行目にこれをコピーします。   │ A│ B  C  D  E│ F ──┼──┼───────────┼────  1│  │ 2  3  5  8│10  2│ 1│ 0  0  0  1│  3│ 2│ 0  0  1  0│  4│ 3│ 0  0  1  1│  5│ 4│ 0  1  0  0│  6│ 5│ 0  1  0  1│  7│ 6│ 0  1  1  0│  8│ 7│ 0  1  1  1│  9│ 8│ 1  0  0  0│ 10│ 9│ 1  0  0  1│OK 11│10│ 1  0  1  0│ 12│11│ 1  0  1  1│ 13│12│ 1  1  0  0│ 14│13│ 1  1  0  1│ 15│14│ 1  1  1  0│OK 16│15│ 1  1  1  1│ 一致する組合せがあればF列に『OK』がでます。 組合せパターンを2進数で表し、掛算して合計を求めています。 3個の数値の場合もすぐできるでしょう。 同じ理屈で、ユーザー定義関数を作れば、単純な繰り返し演算で計算できることになります。 VBAの場合、ビット演算ができるので単純になります。 また、アドインのDEC2BIN関数を使えば、2進数文字列を作ることができます。 アドイン関数を組み込んでいないので上のような方法にしてみました。 ご参考に。

nayaminosuke
質問者

お礼

ありがとうございます。 なんといえばいいのか、逆転の発想というのか、脳味噌が洗われる思いです。 同じ理屈で、・・・以下の文はちょっと私にはむずかしすぎです。。もっと勉強します。

回答No.2

EXCELの関数での方法は、まったく思いつきません。 VBAなら全ての組み合わせを調べれば、できると思います。 必要であれば、補足してください。 VBAのプログラムを作ってみます。(書き方にはあまり自信がありませんが・・・) (VBAが良く分からなければ、修正が難しいと思いますので、その場合は、  数値:Sheet1のA列で個数は未定、ソートされている  求める数値:Sheet1のB1セル  組み合わせの表示位置:Sheet1のC列以降 のように具体的に補足してください)

nayaminosuke
質問者

お礼

いやー、作ってくださるのですか。お世話になります。 VBAは、そこそこ書けるつもりですが、わからないときには、教えてください。

  • nemaro
  • ベストアンサー率28% (40/139)
回答No.1

数学は苦手ですが参考になればうれしい。

参考URL:
http://epnas1.hp.infoseek.co.jp/backnumber/19990724.html
nayaminosuke
質問者

お礼

ありがとうございます。やはり、すべての組み合わせをやってみないとだめみたいですね。うーん。

関連するQ&A