- 締切済み
限られた条件下での合計最大値を求めたい
使用するソフトは、始めはエクセルを想定していますが、最終的にはweb上で計算式を構築することを目的としています。 [前提] 要素A.Bがあり、共に数値が入る Noは行を特定するための便宜上のキー。 No , A , B 1 , 3 , 500 2 , 5 , 740 3 , 8 , 1025 4 , 11 , 3030 といったデータがあり、それぞれに規則性なし。 [目的] A要素の合計がX以内で、かつB要素の合計が最大となる組み合わせを求めたい。 (※)なお、同じNoを何度使用してもいい。 という目的を達するためには、なにか関数や計算方法はあるでしょうか? (※)があると難易度があがったり、不可能な場合には、この条件は省いても構いません。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- amanojaku1
- ベストアンサー率54% (265/488)
訂正です、間違ってました。 >// A要素の合計。 // >fctAMax = 20; // A要素の最大値。 // fctAMax = 20;
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.2 amanojaku1 ざっくりと言うと可能なパターンを総当りしている。
- amanojaku1
- ベストアンサー率54% (265/488)
>web上で計算式を構築することを目的と ファイル名は「test001.htm」とか適当で良いです(拡張子は「htm」にして下さい)。 <head> <meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS"> <!-- charset=Shift-JIS、UTF-8 --> <TITLE>test</TITLE> </head> <body> <script type="text/javascript"> <!-- // A要素の合計。 // fctAMax = 20; // ↑実際は入力でfctAMaxにデータを代入するようにすれば良いでしょう。 fctSupplement = new Array(); fctSource = [ [1 , 3 , 500], [2 , 5 , 740], [3 , 8 , 1025], [4 , 11 , 3030] ] for(let i = 0; i<fctSource.length; i++){ fctSupplement[i] = new Array(); p = 0; // document.write((fctSource[i][1]*(p+1))+'; '+'<br>'); while(fctSource[i][1]*(p+1)<=fctAMax){ fctSupplement[i][p] = fctSource[i][1]*(p+1); document.write(fctSupplement[i][p]+'; '); p++; } document.write('<br>'); } document.write('<br>'); fctPoint = new Array(fctSource.length).fill(-1); fctMaxPoint = new Array(fctSource.length).fill(-1); fctBMax = 0; fctATotal = 0; fctBTotal = 0; fctCurrentRow = 0; fctCurrentColumn = 0; // true,false inc = 0; while(inc==0){ fctATotal = 0; fctBTotal = 0; dbg = ""; for(let i = 0; i<fctSupplement.length; i++){ p = fctPoint[i]; dbg += ""+i+":"+fctSource[i][1]+":"+fctSource[i][2]+"*"+(p+1)+"; "; if(0<=p){ at = fctSource[i][1]*(p+1)+fctATotal; if(fctAMax<at){ break; } fctPoint[i] = p; fctATotal = at; fctBTotal += fctSource[i][2]*(p+1); document.write( 'dbg='+dbg+ '<br>'); document.write( 'i='+i+'; '+ 'fctATotal='+fctATotal+'; '+ 'fctBTotal='+fctBTotal+'; '+ '<br>'); } } if(fctBMax<fctBTotal){ fctBMax = fctBTotal; fctMaxPoint = fctPoint.concat(); document.write( 'fctBMax='+fctBMax+ '<br>'); dbg = ""; for(let i = 0; i<fctMaxPoint.length; i++){ dbg += ""+fctMaxPoint[i]+'; '; } document.write( 'fctMaxPoint='+dbg+ '<br>'); } document.write('<br>'); inc = 1; for(let i = 0; i<fctSupplement.length; i++){ fctPoint[i] += inc; if(fctPoint[i]<fctSupplement[i].length){ inc = 0; break; } fctPoint[i] = -1; inc = 1; } } document.write('<br>'); msga = ""; msgb = ""; for(let i = 0; i<fctMaxPoint.length; i++){ p = fctMaxPoint[i]; if(0<=p){ if(""<msga) msga += "+" if(""<msgb) msgb += "+" msga += ""+fctSource[i][1]+"*"+(p+1); msgb += ""+fctSource[i][2]+"*"+(p+1); document.write( 'No='+fctSource[i][0]+'; '+ 'A='+fctSource[i][1]+'; '+ 'B='+fctSource[i][2]+'; '+ 'Multiply='+(p+1)+'; '+ '<br>'); } } document.write( 'fctATotal='+msga+'='+fctATotal+'; '+ '<br>'); document.write( 'fctBMax='+msgb+'='+fctBMax+'; '+ '<br>'); // --> </script> </body> </html>
- HohoPapa
- ベストアンサー率65% (455/693)
>それぞれに規則性なし かつ、同じNoを複数回使わない場合、 かつ、A要素に0以下の値が無く、 かつ、A要素にx超える値が無い場合を想定し 考えてみました。 要素の最終行の1個を取り出した結果が該当する場合もあれば、 全数を取り出した場合に該当する場合もありうるでしょうから 全ての組み合わせを総当たりしながら、B要素の合計を評価する というロジックにならざるを得ないように思います。 更に、 n個から任意個を選択する組み合わせは 2^n通りありますので、 エクセルのlong型変数を使った場合 扱える要素の数の最大値は、31個になると思います。 (通貨型を使えばもう少し増えると思います) つまり、扱える要素数に限界があるように思います。 コメントしておきながらナンナンですが、 要素の数次第では、私には手に負えないです。 また、複数の組み合わせがヒットした場合に ヒットするすべての組み合わせを列挙することになるのかどうか。 ともあれ、 この辺りを明確にしてからプログラミングすることになりましょう。