• 締切済み

限られた条件下での合計最大値を求めたい

使用するソフトは、始めはエクセルを想定していますが、最終的にはweb上で計算式を構築することを目的としています。 [前提] 要素A.Bがあり、共に数値が入る Noは行を特定するための便宜上のキー。 No , A , B 1 , 3 , 500 2 , 5 , 740 3 , 8 , 1025 4 , 11 , 3030 といったデータがあり、それぞれに規則性なし。 [目的] A要素の合計がX以内で、かつB要素の合計が最大となる組み合わせを求めたい。 (※)なお、同じNoを何度使用してもいい。 という目的を達するためには、なにか関数や計算方法はあるでしょうか? (※)があると難易度があがったり、不可能な場合には、この条件は省いても構いません。 よろしくお願いします。

みんなの回答

回答No.4

訂正です、間違ってました。 >// A要素の合計。 // >fctAMax = 20; // A要素の最大値。 // fctAMax = 20;

回答No.3

>回答No.2 amanojaku1 ざっくりと言うと可能なパターンを総当りしている。

回答No.2

>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% (454/691)
回答No.1

>それぞれに規則性なし かつ、同じNoを複数回使わない場合、 かつ、A要素に0以下の値が無く、 かつ、A要素にx超える値が無い場合を想定し 考えてみました。 要素の最終行の1個を取り出した結果が該当する場合もあれば、 全数を取り出した場合に該当する場合もありうるでしょうから 全ての組み合わせを総当たりしながら、B要素の合計を評価する というロジックにならざるを得ないように思います。 更に、 n個から任意個を選択する組み合わせは 2^n通りありますので、 エクセルのlong型変数を使った場合 扱える要素の数の最大値は、31個になると思います。 (通貨型を使えばもう少し増えると思います) つまり、扱える要素数に限界があるように思います。 コメントしておきながらナンナンですが、 要素の数次第では、私には手に負えないです。 また、複数の組み合わせがヒットした場合に ヒットするすべての組み合わせを列挙することになるのかどうか。 ともあれ、 この辺りを明確にしてからプログラミングすることになりましょう。

関連するQ&A

  • エクセルで条件に合わせて合計を出したい

    いつもお世話になります。 ある列の範囲(B1:B8)の合計を出したいのですが、 条件があり、うまくできません。 (ケース1)    A    B      1  りんご  10         2  なし   10      2  ぶどう  10 4  メロン  20 5  いちご  10 6 7 8 9  合計 0 (ケース2)   A    B   1 りんご  10       2  なし   10      2  ぶどう  10 4  メロン  20 5  いちご  10 6 7 8 9   合計   60 条件というのは、合計する範囲の中に空白(もしくは0)があったら合計しない(もしくは0とする)、 そうでなければ合計値を出す ということです。 上の表のケース1の場合はB3にデータがないので、合計しない、 ケース2は合計する、ということです。 ネックになっているのは上の表では5行目にデータがありますが、 場合によって6行目、7行目、8行目も計算範囲になり、 データがあったり、なかったりするのです。 関数の組み合わせでもマクロでも良いので知恵をお貸し下さい。 わかりにくいところは補足します。よろしくお願いします。

  • Excelで条件に合うデータをピックアップして合計を求めたい

    下記のような条件で合計を求めたいのですが、 SUM関数やSUMIF関数では、求めている合計が得られません。 例) 行/列 A   B    C  1|  No. 金額   氏名 2|  1  200,000  A 3|  1  200,000  B 4|  1  200,000  C 5|  2  150,000  A 6|  2  150,000  D 7|  3  180,000  B 8|  3  180,000  D 9|  3  180,000  E 10| 小計  上記のようなデータがあります。 B列には、Noごとに、それぞれ同じ金額が重複して入力してあります。 ここから、Noの最初の金額である200,000+150,000+180,000=530,000 という合計を10行目に求めたいのです。 現在は、自分でNoを確認しながら、その都度、 合計したいセルを選択して合計を求めているのですが、 データ数が多いため、何か別の方法がないかと思案しております。 どなたか、アドバイスの程、宜しくお願いします。

  • 条件があったものだけ合計

    条件があったものだけ合計する数式を使用したいのですが うまくいかないので質問させてください。 エクセルのバージョンは2003を使用しています。 例えばA1に日付、B1にお店、C1に商品、D1に金額が入力されており、 以下100行まで同じ関係(但し日付はランダム、お店はランダム...)で入力されているとします。 そこでF1に、A1:C100の中で、 A1が○○、B1が○○、C1が○○の条件のときの D列つまり金額の合計を出力、という風にしたいのです。 分かりにくければ補足しますので、 どうか宜しくお願い致します。

  • Excel 合計の出し方について

    Excelのカウントについて質問です。      A列   B列 1行目 1-2-3  1200 2行目 2-3-1  800 3行目 4-5-1  400 4行目 3-2-1  2000 5行目 1-3-2  500 6行目 答え→ ( 4500 ) 上記の表があり、B列6行目にA1~A5の内容を確認し、 条件に応じた計算結果を出したいです。 条件としては、1-2-3、2-3-1、3-1-2など、同じ数字で構成されているものであれば、順番が違っていても同じものとみなして合計します。 ※ちなみに1-2-3は文字列です。 ※上記の表では、1-2-3でできる組合せの合計で4500という答えを出してます。 思いつくままに関数を書いてみました。 =SUM(SUMIF(A1:A5,{"1-2-3","1-3-2","2-1-3","2-3-1","3-1-2","3-2-1"},B1:B5)) これでもできなくはないのですが、組合せをたくさん書くのがとても面倒で、 仮に、1-2-3-4 や、1-2-3-4-5 など組合せが多くなった場合はとても上記のやり方では対応できません。また、組合せは1桁だけでなく2桁(1-3-10)、3桁(5-80-100)も存在します。 効率良く書ける方法があればおしえてください。

  • EXCEL合計について

    Excelの関数についての質問です。      A列   B列 1行目 1-2-3  1200 2行目 2-3-1  800 3行目 4-5-1  400 4行目 3-2-1  2000 5行目 1-3-2  500 6行目 答え→ ( 4500 ) 上記の表があり、B列6行目に条件に応じた計算結果を出したいです。 条件としては、1-2-3、2-3-1、3-1-2など、同じ数字で構成されているものであれば、順番が違っていても同じものとみなして合計します。 ※1-2-3は文字列です。 ※上記の表では、1-2-3でできる組合せの合計でB6に4500という答えを出してます。 思いつくままに関数を書いてみました。 =SUM(SUMIF(A1:A5,{"1-2-3","1-3-2","2-1-3","2-3-1","3-1-2","3-2-1"},B1:B5)) これでもできなくはないのですが、組合せをたくさん書くのがとても面倒で、 仮に、1-2-3-4 や、1-2-3-4-5 など組合せが多くなった場合はとても上記のやり方では対応できません。また、組合せは1桁だけでなく2桁(1-3-10)、3桁(5-80-100)も存在します。 前回こちらで以下の書き方をおしえていただいたのですが、 =SUMPRODUCT((ISNUMBER(FIND(TRIM(MID(SUBSTITUTE(A6,"-",REPT(" ",100)),1,10)),A$1:A$5))*ISNUMBER(FIND(TRIM(MID(SUBSTITUTE(A6,"-",REPT(" ",100)),100,10)),A$1:A$5))*ISNUMBER(FIND(TRIM(MID(SUBSTITUTE(A6,"-",REPT(" ",100)),200,10)),A$1:A$5))),B$1:B$5) こちらですと 1-12-3と1-2-3が同類とみなされて一緒に合計されてしまいます。 2桁以上でも対応できるやり方か、他にもっと効率の良い求め方があれば教えて下さい。

  • 要素数を最大化する組合せ最適化問題について

    要素数を最大化するような組合せ最適化問題(線形計画問題)を解こうとしていますが、 要素数を一度に計算したり、ソートしたりすることはできません。 (そのような関数を線形式で定義するのは難しいと思いますので。) 一方、2つの要素が同一かどうかのみの計算は簡単にできるので、 全ての2要素間で一致/不一致を判断し、不一致の数が最大となるように目的関数を設定して、この問題を解こうかと思っています。 この方法は正しいでしょうか。 例えば、 ある変数の組合せにおいて、 A1=X, A2=Y, A3=X といった結果になるとすると、 bin1=|A1-A2|(=1、不一致) bin2=|A1-A3|(=0、一致) bin3=|A2-A3|(=1、不一致) という風に要素の一致/不一致を計算し、 不一致数(=bin1+bin2+bin3)を最大化するという風に目的関数を定義しようかと思っています。 当然、不一致数と要素数は一致しないわけですが、 不一致数が最大のときに、必ず要素数が最大となるのであれば、 目的関数として問題ないと考えています。 なんとなく正しい気もしますが、本当に正しいのかよくわかりません。 よろしくお願いします。

  • 表計算(ある条件にそうものだけを合計したい)

    Excelで、表にあるようなものを作っています。 氏名(セルB4:E4)の頭文字に“A”もしくは“B”がついており、各科目(B5~E9)の点数が出ています。 この“A”の頭文字がついている人の1月の合計点を“A 合計”(セルF5~F9)に出し、Bの頭文字がついている人は、“B 合計”(セルG5~G9)にそれぞれ出していきたいと思っています。 その場合の計算式は、どのようになりますでしょうか? 初歩的かもしれませんが、どうか助けてください。 よろしくお願い致します。

  • 表からある条件に合うもののみの合計を出したい

    エクセル2010を使用しています。 A列とB列とC列があり、A列には6種類ほどのコードがあります。B列には金額、C列には人の名前があります。 例 A     B    C 001  3,000  太郎  015 45,862  花子 025 210  一郎 020 147,585  次郎 015 1,000  愛子 030 51  三郎 001 58,956  梅子 025 5,846  桜子 ここからコードが001のもののBの合計額、015のBの合計額、020の・・・・といった具合にA列での各コード別の合計額を算出したいと思っています。 フィルタでなく、関数で行うには、どのような式を作ればいいでしょうか?よろしくお願いします。

  • 複数の条件が一致する合計。

    複数の条件に一致する合計を求める方法には、 =SUM(IF(A1:A10="○",IF(B1:B10="○",C1:C10,0),0)) とセルに入力し、Ctrl+Shift+Enter =SUMPRODUCT((A1:A10="○")*(B1:B10="○")*(C1:C10)) があると思うのですが、このそれぞれの範囲の部分を列全体で指定したいんです。 ですが、A:Aのようにするとエラーになるし、A1:A65536にすると計算(再計算)にすごく時間がかかります。 SUMIFだと列全体を指定してもすぐ計算(再計算)されるのですが、条件が複数になったときでも列全体を指定できてすぐ再計算される方法はないですか?

  • 条件で合計を分ける?方法を教えていただけますか?

    どなたかお分かりになる方、教えていただけますでしょうか? 下記添付画像のようなエクセル表があります。 この表から、テストの点数の総合計が50点以上で、かつ科目「英」と「数」の合計も50点以上の人は「Yes」、そうでない人物は「No」ということが、すぐに分かるような表を作りたいのです。 例えば、Aさんはこれまで4つのテストを受けており、そのテスト全ての合計点数が80点で、かつ「英」と「数」の総合計70点なので、「Yes」 Bさんは、これまでテスト2つで総合計が50点、「英」「数」の総合計も50点なので「Yes」、 Cさんは3つのテストで総合計は60点だけれど、「英」「数」の合計が30点なので「No」、 Dさんは1つのテストで総合計50点だけれど、「理」以外のテストを受けてないので「英」「数」総合計0点なので「No」 色々考えたのですが、私の知識では全く思いつかず。。。 お分かりになる方がいらっしゃいましたら、ご教授いただけないでしょうか。 どうぞよろしくお願い致します。

専門家に質問してみよう