プロが教えるわが家の防犯対策術!

例えば、1~10の数字があって、その中から合計が10になる組み合わせを探す、という計算式はExcelで作成することはできますか?(答えは[1+2+3+4][1+2+7][1+3+6][1+4+5][1+9][2+3+5][2+8][3+7][4+6]の9通り)
もしくは、複数の組み合わせで計算させて、合計が10になったものを検索するという計算式は可能でしょうか?
よろしくお願いします。

A 回答 (3件)

こんばんは。



ソルバーでやってみようとしたけれど、「解」が見つかりませんでしたので、それは、たぶん、VBAしか無理ではないかと思います。以下で、作ってみました。あまり、大きな数を代入しないでくださいね。

下記の
要素の数:9 というのは、1~9までのこと
合計の目的の数:10 というのは、合計の数値のこと

後は、いじらなくてよいと思います。


'<標準モジュール>
'-----------------------------------------------------------
Private Const N As Integer = 9 '要素の数
Private Const TARGETNUM As Integer = 10 '合計の目的の数

Private k As Integer '取り出される要素数
Private buf() As Integer '出力の際のバッファ
Private ar() As Integer '要素を格納する配列
Private i As Integer
Private j As Integer
Private m As Long

Sub Init()
  Dim flg() As Boolean
  ReDim ar(1 To N)
  ReDim flg(1 To N)
  Range("A1").CurrentRegion.ClearContents
  For k = 2 To Int(N / 2)
    ReDim buf(1 To k)
    j = 0: m = 0
     For i = 1 To N
      ar(i) = i
    Next i
    Comb 1, flg(), 0
  Next k
End Sub
Private Function Comb(Lb As Integer, flg() As Boolean, Used As Integer)
If (N - Lb + 1 + Used < k) Then Exit Function
  If (Used = k) Then
   For i = Lb To N
     flg(i) = False
   Next
   j = 0
   For i = 1 To N
     If flg(i) Then
      buf(j + 1) = ar(i)
      j = j + 1
     End If
   Next
   Call WorkOut(buf())
   m = m + 1
   Exit Function
  End If
  flg(Lb) = True
  Comb Lb + 1, flg(), Used + 1
  flg(Lb) = False
  Comb Lb + 1, flg(), Used
End Function
Private Sub WorkOut(BaseArray() As Integer)
Dim rw As Long
  Application.ScreenUpdating = False
  rw = Range("A65536").End(xlUp).Offset(1).Row
  If WorksheetFunction.sum(BaseArray()) = TARGETNUM Then
    Cells(rw, 1).Resize(, k).Value = BaseArray()
  End If
  Application.ScreenUpdating = False
End Sub

この回答への補足

ご回答ありがとうございます!

ところで、大きな数字を代入しないでと書いてあるのですが、どれくらいの桁数を入れてしまうとダメでしょうか?
また、もしVBA以外の手段をご存知でしたら教えて頂けますか?

補足日時:2006/03/23 02:18
    • good
    • 1

既に答えがでていますが、私も作ってみました。


(最近似たような問題( http://okwave.jp/kotaeru.php3?qid=1999665 )をやったのでそれの焼き直し)
----------------------------------------------------------------
Private List() As Integer
Private Level As Integer
Private Count As Integer '組み合わせの総件数

Public Sub partition() 'プログラム起動のきっかけ
Dim n As Integer
Count = 0
Level = -1
n = 10 ' 合計となる数
Range("A1").Value = "1~" & n & "の数字があって、その中から合計が10になる組み合わせを探す"
ReDim List(n)
Call part(n)
Debug.Print Count & "通り"
End Sub

Private Sub part(n As Integer)
Dim i As Integer
Dim first As Integer
Dim result As String
If n < 1 Then Exit Sub
Level = Level + 1
List(Level) = n
result = ""
For i = 0 To Level
result = result & List(i) & "+"
Next
result = Left(result, Len(result) - 1)
Range("A2").Offset(Count).Value = result
Count = Count + 1
If Level = 0 Then
first = 1
Else
first = List(Level - 1) + 1
End If
For i = first To n \ 2
List(Level) = i
If n - i <> i Then
Call part(n - i)
End If
Next
Level = Level - 1
End Sub

この回答への補足

ご回答ありがとうございます!

同じ質問になってしまいますが、VBA以外で他に方法をご存知でしたら教えて頂けますか?

補足日時:2006/03/23 02:23
    • good
    • 1

こんにちは。



>大きな数字を代入しないでと書いてあるのですが、どれくらいの桁数を入れてしまうとダメでしょうか?

というよりも、元々、ご質問の主旨は、数学的な問題だと理解したのですから、それが、どうなるのかは、後は、PCの性能とか、Excelの仕様とかに制約されるということです。たぶん、配列変数のバッファの大きさに関係するものだと思いますが、おやりになってみるのが早いのではありませんか?

数学的な問題としては、この2点の解答で、私は、解決していると思っておりますので、ご質問者が、今、現実に抱えている問題を解決できるのかどうなのかは、こちらからでは分りません。それに、ご質問なさったことは解決しているのではないでしょうか?

>また、もしVBA以外の手段をご存知でしたら教えて頂けますか?

そういうことは、ご質問の時点で明示してください。もちろん、私は、VBA以外を検討した上で、回答をしています。こちらの書いた内容を良く読んでください。

おそらくは、市販のソルバーを購入されればよいのではないかと思います。社名は、Microsoft のサポートに出ているかと思いますが、ソルバー社といいます。Microsoft社では、以下の会社のソルバーを薦めています。

http://www.solver.com/
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています