• ベストアンサー

複数の数字の中からどれかを足して合計を出す方法

いつもお世話になっております。 過去にも同様の質問がありましたが、ナップザック問題について教えていただきたく思います。 エクセルのA列に50個程の数値(千円単位~1千万円単位)が入っています。 その中のどれかを足し合わせて、特定の数字を探したいのです。 (求めたい数字21,069,182) (例) 10 5  12 2 なら、15になるのは10と5の組み合わせで、10と5を求めるような感じです。 過去の質問を読み、エクセルのVBAをコピーしてやったりしましたが、フリーズしてしまったり、オーバフローなどになってしまいます。 50個と数字が多いのが問題なのでしょうか・・・ 何か良い方法がございましたら、ご教授いただきたく思います。 よろしくお願いします。

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

  • ベストアンサー
noname#140971
noname#140971
回答No.1

一介の服飾デザイナですが、パッと思い付いたアルゴリズムは次のようです。 まず、クイックソートでもバブルソートでも構わないので昇順に並べます。 2,5,10,12 2+5---------------7 (7+5=12 next) 2+5+10------------17 (stop) 2+10--------------12 (2+10+10=22 Stop) 2+12--------------14 (Stop) 5+10--------------15 hit 10----------------10 (10+10 Stop) 次に、小さい数字から順次足していきます。 次を加算するのは、同じ数字を足して目的値に等しいか以下である場合。 もちろん、結果オーバーしていれば即抜けます。 次を加算するべきか否かは、最初の1個でも判定する必要があります。 そうすれば、10以上はテストする必要がないことが判ります。 プログラマでも何でもないので参考程度にして下さい。

kazuhakase
質問者

お礼

ご回答ありがとうございます。 例がちょっと言葉足らずであったかもしれませんが、 二つの数字のみで答えが出るとは限らないんです。 50個の数値のうち25個足して数字が出るか あるいは40個足して数字が出るか・・・ この場合、難しいですよねぇ・・・

その他の回答 (6)

noname#140971
noname#140971
回答No.7

ゴミ回答をしたので、もう、少し補足しておきます。 5つの組み合わせがみつかったら、その要素同士の組合せの個数分だけチェック。 1+5->6 1+5+6->12 5+6->11 6、11、12があれば、それも組合せ。 次は、これを一つづ見つけなきゃならんですね。 まあ、しんどい話ですね。 だが、これで Husky流のアルゴリズムは見えてきたと思います。 なお、軽々な回答、お詫びしておきます。

noname#140971
noname#140971
回答No.6

総当り法・・・なるほどですね。 私の書いたコードは、さらに、修正しなきゃならんですね。 私が見つけているのは、最も、多い要素での組み合わせ。 次は、それより1個少ない組み合わせを見つけにゃならんですね。 そういう意味では、次のループは最初の検索のそれ。 総当り法・・・なるほどですね。 酒飲みながら書くようなコードじゃなかったですね。 反省!

noname#140971
noname#140971
回答No.5

総当り法のコードを眺めてみました。 事前に昇順ソートされていないデータを総当りしている感じですね。 問題は、コードを真似るのではなくアルゴリズムを理解すること。 例えば、クイックソートのアルゴリズムを理解するのに私はカードを使いました。 「あー、なるほど。このような要領で並び替えているのか」 コードを書くというのは、決して、知的な作業ではないです。 一旦、アルゴリズムを理解してしまえば、コード書きは単なる肉体労働です。 先ずは、アルゴリズムを「ガッテン!」と思うまで解読されたし。 なお、私の回答は、組み合わせは求めることが可能。 だが、エクセルのどのセルかには答えられません。 しかし、値と取り込む際に、10,20,15,234 を 10.01, 20.02,15.03,234.04と変換して取り込めば、それも可能です。

noname#140971
noname#140971
回答No.4

ちょっと、回答に自信がなかったのでコードを書いてみました。 確かに、100になる組み合わせを見つけました。 もちろん、素人が酒飲みながら書いたコード。 ちゃんと URL のやり方を参照されて下さい。 [イミディエイト] 10, 15, 20, 25, 30, Private Sub Command1_Click()   Dim H     As Integer   Dim I     As Integer   Dim N     As Integer   Dim M     As Integer   Dim Target  As Integer   Dim Amount(9) As Long   Dim strUnit  As String      Amount(0) = 10: Amount(1) = 20: Amount(2) = 30: Amount(3) = 40: Amount(4) = 50   Amount(5) = 45: Amount(6) = 35: Amount(7) = 25: Amount(8) = 15: Amount(9) = 5   ' ------------   ' 昇順ソート   ' ------------   QSort Amount(), 0, UBound(Amount())   ' ----------------------------------   ' 100 になる組合せを求める   ' ----------------------------------   Target = 100   For I = 0 To 9     strUnit = Str(Amount(I)) & ","     M = Amount(I)     H = I + 1     If M = Target Then       Debug.Print strUnit     ElseIf M * 2 <= Target Then       For J = H To 9         M = M + Amount(J)         strUnit = strUnit & Str(Amount(J)) & ","         If M = Target Then           Debug.Print strUnit           Exit For         ElseIf M + Amount(J) > Target Then           Exit For         End If       Next J     End If   Next I End Sub Public Sub QSort(ByRef Datas() As Long, ByVal intTop As Integer, ByVal intLast As Integer)   Dim I As Integer   Dim J As Integer   Dim R As Integer   Dim N As Integer   Dim Temp As Long   Dim Part As Long   N = intLast - intTop + 1   If N < 2 Then     Exit Sub   End If   Part = Datas(intTop + Int(N / 2))   I = intTop - 1   J = intLast + 1   Do     Do       I = I + 1     Loop While Datas(I) < Part     Do       J = J - 1     Loop While Datas(J) > Part     If (I < J) Then       Temp = Datas(I): Datas(I) = Datas(J): Datas(J) = Temp     End If   Loop Until (I >= J)   R = N - I   QSort Datas(), 0, I - 1   QSort Datas(), I, I + R - 1 End Sub

kazuhakase
質問者

お礼

ご回答ありがとうございます。 URLの方法を参考にしながらやってみましたが、フリーズしてしまって先に進めない状態です。 20個位の少ない数字なら大丈夫なんでしょうけど、50個もあり、 しかも桁が多い場合は時間ばかりかかり答えを求めるのは不可能なようですね・・・

noname#140971
noname#140971
回答No.3

そのナップザック問題に関しては無知ですが、2個でも30個でも同じじゃないですかね。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.2

どのようなVBAを試されたのか分からないのですが、総当たり法では2^50-1通りの計算が必要になり、EXCELの有効桁数を超えてしまいます。下記URLの動的計画法をお試しになってはいかがでしょうか。 (既にお試しなら読み飛ばしてください) ただし時間がかかるのは覚悟してください。フリーズと見えても本当に計算中なのだと思いますよ。 http://www.geocities.co.jp/SiliconValley-Oakland/8139/

kazuhakase
質問者

お礼

ご回答ありがとうございます。 動的方法を試しましたが、やはりフリーズしてしまいました。 メモリが少ないので、50個の数値は厳しいです・・・

関連するQ&A