塗料の無駄を削減するためライン改善を行っています。前回にこの無駄が数値化ができたから、
製品の様々なグループ分けのなかで最適なグループ分けが検出が可能です。いくつかのテクニックが使えそうですが、
最適化問題にもなるためなんとなく線型計画法が使えるかもしれないと思いました。
続いて、まず問題を分割し、制約の数式化を行う必要があります。
問題の分離
製品を塗装するときに横幅(①)、上限位置(②)、塗装長さ(③)の3つのパラメータがあり、
これらのパラメータごとに無駄が最も少ないグルーピングを探します。
グルーピングを同時に決めて、総合的に評価するとかなり大変な作業になりますが、
もしパラメータの最適なグルーピングを1つずつ見つけて固定することができれば、
既に決めたグルーピングの定義を次のパラメータグルーピングの最適化に使えるから、
まずはパラメータごとにグルーピングを決める方法を検討します。
方針が決まったから、今度は最小にしたい無駄の定義に対して各パラメータの影響を確認します。

縦軸に上限位置、塗装長さの2つのパラメータが関わることに対し、横軸に横幅のパラメータだけになるため
まずはそちらから攻めた方が簡単そうです。横幅の設定を評価するため、
製品の横幅より広くなる部分(上の図の黄色い領域)の無駄を最低限になる設定を採用したいです。
残りのパラメータグルーピングを決める順番は自然と決定されます。
上限位置が分からないと塗装範囲内に入ってしまうハンガーの部分が分からないため、
塗装長さを決めた状態でないと上限位置が決めれなくなる可能性があります。
そのため、先に上限位置のパラメータを製品の上の部分(上の図の赤いとオレンジの領域)の無駄を最低限にし、
最後に塗装長さのパラメータを製品の下の部分(上の図の青いと緑の領域)の無駄を最低限にします。
数式化
問題の分離ができたので、次は横幅パラメータのグルーピングを線型計画法で決定するための変数と制約関数、
最適化したい表現を考える必要があります。最適化したい表現にどんな変数を定義しなければならないことを考えながら、
その変数の関係を制御するための関数を洗い出します。
まず、最適化したい値は先ほど話に出いているの塗料の無駄になります。つまり、
製品に該当する横幅設定と実際の製品横の差を計算して製品の長さと掛けると
横幅パラメータによりその製品を塗装する際に発生する無駄がわかります。
例えば、158mm長さの製品の横幅が43mmに対して横幅グループの幅が60mmなら
2686mm2分の無駄になりますが、
80mmの横幅グループの場合、5846mm2分の無駄になります。
(60−43)∗158=2686mm2(80−43)∗158=5846mm2 
グループ変数定義
上の式のグループ幅を変数にして、9グループがあるため
グループ1の幅を表す変数のg1からグループ9の幅を表す変数のg9まで、9つの変数を用意する考えもあるかもしれません。
しかし、60mmのグループがあれば、それはグループ1なのか、グループ2なのかは特に関係ありません。
また、どのグルーブがどの製品に該当するかはこの変数の値次第になってしまうため、数式がピンときません。
そんな思考よりも、少なくとも自分にとってはブーリアン変数を使うことがより考えやすいです。
例えば、g60を定義して、幅60mmのグループがあるとg60の値が1、
幅60mmのグループがないとg60の値が0になります。
20mmから200mmまでの幅を網羅するため、
g20,g21,...,g199,g200({gi∣i∈[20,200]})を定義します。
9グルーブが欲しので、これらの変数の中で9つが1になり、
それ以外の変数が0にならないといけないので、
その制御を数式で表します。
∑i=20200gi=9
また、200mmのグルーブがないと200mm幅の製品が対応できないので、
g200が必ず存在するように数式を用意します。
g200=1
例えば、前回の一定幅で分けたグルーピング、
(40mm, 60mm, 80mm, 100mm, 120mm, 140mm, 160mm, 180mm, 200mm)であれば
g40, g60, g80, g100, g120, g140, g160, g180, g200が1になり、
それ以外のgiが0になります。そのため、giの和が9になり、g200が1ので以上の数式を満たします。
ここで問題:最終的に最低限にしたい無駄を計算するために各製品に該当するグループが特定しないといけません。
これらのg変数があれば、例の43mm幅の製品に該当するグループはどう特定しますか?
まずは、g43が1の場合、43mmのグループがあり、ピッタリなのでそのグループが例の製品に該当します。
g43が0なら、今度g44が1なら44mmのグループになります。
逆に、g42が1だとしても例の43mm幅の製品に対して幅が足りません。
つまり、
immのグループが43mm幅の製品に該当する⟺gi=1∧(且つ)gk=0∀(任意の)k∈[43,i−1]
(もしgiが1 且つ 任意の[43,i−1]の範囲の整数kに対してgkが0 のであれば、immのグループが43mm幅の製品に該当する)
例えば、結果の9グループに60mmのグループがあり(g60=1)、
43mm、 44mm、...、 59mmのグループがない(g43=0,g44=0,...,g59=0)
のであれば(g60=1∧gi=0∀i∈[43,59])60mmのグループが例の43mm幅の製品に該当します。
代わりにg80=1∧gi=0∀i∈[43,79]であれば、80mmのグループがあり、そのグループが例の43mm製品に該当します。
これを一般的な製品を対応するルールにすると以下になります。
immのグループがjmm幅の製品に該当する⟺gi=1∧gk=0∀k∈[j,i−1]
無駄変数定義
この思考をたどって、無駄の有無も刻んでみてはどうでしょうか。
もし43mm幅の製品が60mmグループに該当すれば、43mm-60mmの無駄が発生します。
これを刻むと43mm-44mmの無駄、44mm-45mmの無駄、...、58mm-59mmの無駄、59mm-60mmの無駄が発生します。
逆に、グループ幅は60mmなのでそれ以上の幅を塗装しなく、60mm-200mmの無駄(60mm-61mmの無駄、...、199mm-200mmの無駄)が発生しません。
これらの無駄発生変数を定義してみましょう。43mm-44mmの無駄が発生するかどうかの変数m44、
44㎜-45㎜の無駄が発生するかどうかの変数m45など、{mi∣iが無駄の幅}でどうでしょう。
例の43mm幅の製品と60mmグループの組み合わせで考えれば、
mi=1∀i∈[44,60],mj=0∀j∈[61,200]になるといいです。
ここで問題は気づくでしょうか?違う幅の製品を加えてみるとどうなるでしょう。
まず、20mm-43mmの無駄(20mm-21mmの無駄、...、42mm-43mmの無駄)の話は一切出てません。
43mm幅の製品のであれば、20mm-43mmは塗る部分になり無駄が発生しているわけではないので、
mi=0∀i∈[21,43]でいけるのかもしれません。
でも、60mmグループが該当しない製品の場合はどうでしょう。
例えば、他に42mm幅の製品が43㎜幅の製品と同じく60mmのグループに該当すれば、
その製品に対して42mm-43mmの無駄が発生し、m43は1にならなければなりません。
厳密言えば、このmiの変数はあくまでも最小化したい無駄の計算式のために定義しているのです。
42mm-43mmの無駄は43㎜幅の製品に発生しないため、43㎜幅の製品に対する無駄はm43の係数に加算されないので、
これは何とかなりそうです。
しかし、70mm幅の製品があると60mmのグループに該当せず、
43幅の製品に対して70mm-71mmの無駄が発生しない(m71=0)が
70mmのグループがない限り、70mm幅の製品に対してこの無駄が発生する(m71=1)ことになります。
m71が同時に0でも1でもなることができないので、今の変数定義では物足りません。
こうなると、製品毎に無駄有無の変数を定義するとどうでしょう。
厳密言うとこの変数は製品毎にというより製品の幅毎に定義したいと思います。
そうすると、43mm幅の製品の変数を{mi,j∣i∈製品の幅,j∈[i+1,200](無駄の幅)}を
定義し直します。例えば、m43,44が43mm幅の製品に対して43mm-44mmの無駄が発生するかどうか、
m43,45が43mm幅の製品に対して44mm-45mmの無駄が発生するかどうかを表します。

この変数を使えば幅のグルーピングで発生する無駄の計算式が定義できます。
例の43mm幅、158㎜長さの製品の無駄が以下の式で表現できます。
i=44∑200158∗m43,i 60mmグループがこの製品に該当すると
m43,i=1∀i∈[44,60],m43,j=0∀j∈[61,200]になるから、
==i=44∑60(158∗1)+i=61∑200(158∗0)158∗(60−44+1)+0∗(200−61+1)2686mm2 上と同じ結果ですね、よかった!
全ての製品の無駄の和をとると、最小値を求める表現が定義できます。
次は、この無駄の変数とグループの変数の関係を表す関数を定義する必要があります。
上出題したところを見返すと、以下のパターンが出てきます。
m43,44m43,45...m43,60...m43,200一般的な無駄の幅ですとm43,j一般的な製品幅ですとmi,j=1=1=1=1=1=1⟺⟺⟺⟺⟺⟺g43g43gkgkgkgk=0=0∧g44=0=0∀k∈[43,59]=0∀k∈[43,199]=0∀k∈[43,j−1]=0∀k∈[i,j−1] 数式に直すと
00...0...0一般的な無駄の幅ですと0一般的な製品幅ですと0<<<<<<2∗17∗157∗(j−43)∗(j−i)∗m43,44m43,45m43,60m43,200m43,jmi,j++++++g43g43+g44k=43∑59gkk=43∑199gkk=43∑j−1gkk=i∑j−1gk<=<=<=<=<=<=1217157(j−43)(j−i) まとめ
長くなってしましましたが、
これで制御の式と最小化した式が全て定義しました。次回はやっとこれをプログラムにします。
ただその前に、変数が結構多くなり、少なくできると処理速度の短縮が可能です。
何か変数を減らす方法が思いつくのでしょうか。これも次回検討しましょう。