いつもお世話になっております。
過去にも同様の質問がありましたが、ナップザック問題について教えていただきたく思います。
エクセルのA列に50個程の数値(千円単位~1千万円単位)が入っています。
その中のどれかを足し合わせて、特定の数字を探したいのです。
(求めたい数字21,069,182)
(例)
10
5
12
2
なら、15になるのは10と5の組み合わせで、10と5を求めるような感じです。
過去の質問を読み、エクセルのVBAをコピーしてやったりしましたが、フリーズしてしまったり、オーバフローなどになってしまいます。
50個と数字が多いのが問題なのでしょうか・・・
何か良い方法がございましたら、ご教授いただきたく思います。
よろしくお願いします。
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以上はテストする必要がないことが判ります。
プログラマでも何でもないので参考程度にして下さい。
ご回答ありがとうございます。
例がちょっと言葉足らずであったかもしれませんが、
二つの数字のみで答えが出るとは限らないんです。
50個の数値のうち25個足して数字が出るか
あるいは40個足して数字が出るか・・・
この場合、難しいですよねぇ・・・
No.2
- 回答日時:
どのようなVBAを試されたのか分からないのですが、総当たり法では2^50-1通りの計算が必要になり、EXCELの有効桁数を超えてしまいます。
下記URLの動的計画法をお試しになってはいかがでしょうか。(既にお試しなら読み飛ばしてください)
ただし時間がかかるのは覚悟してください。フリーズと見えても本当に計算中なのだと思いますよ。
http://www.geocities.co.jp/SiliconValley-Oakland …
ご回答ありがとうございます。
動的方法を試しましたが、やはりフリーズしてしまいました。
メモリが少ないので、50個の数値は厳しいです・・・
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
ご回答ありがとうございます。
URLの方法を参考にしながらやってみましたが、フリーズしてしまって先に進めない状態です。
20個位の少ない数字なら大丈夫なんでしょうけど、50個もあり、
しかも桁が多い場合は時間ばかりかかり答えを求めるのは不可能なようですね・・・
No.5
- 回答日時:
総当り法のコードを眺めてみました。
事前に昇順ソートされていないデータを総当りしている感じですね。
問題は、コードを真似るのではなくアルゴリズムを理解すること。
例えば、クイックソートのアルゴリズムを理解するのに私はカードを使いました。
「あー、なるほど。このような要領で並び替えているのか」
コードを書くというのは、決して、知的な作業ではないです。
一旦、アルゴリズムを理解してしまえば、コード書きは単なる肉体労働です。
先ずは、アルゴリズムを「ガッテン!」と思うまで解読されたし。
なお、私の回答は、組み合わせは求めることが可能。
だが、エクセルのどのセルかには答えられません。
しかし、値と取り込む際に、10,20,15,234 を 10.01, 20.02,15.03,234.04と変換して取り込めば、それも可能です。
No.6
- 回答日時:
総当り法・・・なるほどですね。
私の書いたコードは、さらに、修正しなきゃならんですね。
私が見つけているのは、最も、多い要素での組み合わせ。
次は、それより1個少ない組み合わせを見つけにゃならんですね。
そういう意味では、次のループは最初の検索のそれ。
総当り法・・・なるほどですね。
酒飲みながら書くようなコードじゃなかったですね。
反省!
No.7
- 回答日時:
ゴミ回答をしたので、もう、少し補足しておきます。
5つの組み合わせがみつかったら、その要素同士の組合せの個数分だけチェック。
1+5->6
1+5+6->12
5+6->11
6、11、12があれば、それも組合せ。
次は、これを一つづ見つけなきゃならんですね。
まあ、しんどい話ですね。
だが、これで Husky流のアルゴリズムは見えてきたと思います。
なお、軽々な回答、お詫びしておきます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- Excel(エクセル) SUMIF関数について 4 2023/06/14 13:13
- その他(Microsoft Office) ある表(10桝程度)の中に数字が入っています。ダブっている数字を除く数字の合計数の計算方法 5 2023/02/15 11:33
- 数学 時々、回答者の見識に疑念を抱いてしまうんです。私だって本当は皆様のことを疑いたくはありません。しかし 2 2022/11/27 12:23
- 高校 有効数字計算 確定した値を含む 2 2023/01/18 06:03
- その他(プログラミング・Web制作) 2つのテキストファイルを比べて文字列を特定する方法を教えて下さい 5 2022/05/01 15:22
- Visual Basic(VBA) VBA 「,」・空白・カタカナ等の複数条件のマクロ 2 2023/08/23 11:57
- 高校 高校化学、気体、温度の有効数字 3 2023/04/02 11:39
- PHP 【スプレッドシート】順位のつけ方 2 2022/08/17 13:27
- Visual Basic(VBA) エクセルVBAについて 2 2023/01/31 16:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
正しい五十音順について
-
アルゴリズムとプロトコールの違い
-
Dijkstraて
-
C言語初心者の質問失礼いたしま...
-
画像から文字を認識してテキス...
-
[ EXCEL VBA ] 図形を読み込む...
-
期間重複チェックがわかりません
-
プログラミング能力とアルゴリ...
-
「FFTW」についての質問です。
-
C# 再帰よるスタックオーバー...
-
連立方程式を解く
-
タテヨコで数字の被らない二次...
-
アルゴリズムが全くわからない
-
アルゴリズム オーダー記法 定...
-
対話型遺伝的アルゴリズムにつ...
-
BCDについて
-
ランダム関数を作りたい。
-
Vba 実数および実数タイプの変...
-
0除算して、落ちるプログラムと...
-
VBAで仕様書は書きますか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
正しい五十音順について
-
Dijkstraて
-
Stuck
-
[ EXCEL VBA ] 図形を読み込む...
-
BCDについて
-
アルゴリズムとプロトコールの違い
-
期間重複チェックがわかりません
-
グループを均等に分けるには?...
-
三次元形状曲面の導出法
-
あいまい検索(文字列一致率)
-
Visual studio2019 C#で生まれ...
-
gooという検索エンジンの後にGo...
-
フリーセルの難易度について
-
CRC-CCITT16の算出法
-
経路探索について
-
C♯で電卓を作成しています。演...
-
理系の高校生です。大学で情報...
-
OpenCVのライセンスについて
-
偏りのある乱数のアルゴリズム
-
詰め将棋をとくのは、アルゴリ...
おすすめ情報