2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

生産現場で役に立つかもしれない最適化手法3【表計算ソフトのソルバー】(工数の平準化)

Posted at

<--目次へ

はじめに

表計算ソフトのソルバーを使った方法です。
やっていることは「生産現場で役に立つかもしれない最適化手法2」とほぼ同じですが、小さなロットに分割し複数の日に生産を分けられるようにしています。

最適化の条件

  • 製品ごとに必要な工数が与えられており、日ごとの最大総工数以内になるように生産計画を立てたい。
  • 各製品の生産はロットに分割できる
  • 製品の製造できる期間は決まっているが、生産する順は任意

ソルバーで

LibreOffice Calcのソルバーでやってみました。
EXCELでも同じようにできるはずです。
まず文字や数値を次のように書き込みます。
t1.png

セルG2に下図の式を入れ、下方向にG6までコピーします。ロット数の合計を計算しています。
t2.png

セルD7に下図の式を入れ、右方向にF7までコピーします。工数の合計を計算しています。
t3.png

G9に生産できない日に相当するセル(工数が0になる)の合計の計算式を入れます。
t4.png

ソルバーへの入力です。
t5.png

「変更させるセル」で変数領域のセルを指定します。ロット数が入りますので、
制約条件で、その領域のセルが整数でかつ0以上になるように制約します。

制約条件3行目はロット数の合計が一致するように
制約条件4行目で各日の工数の上限を超えないように制限しています。

どうも「ターゲットセル」を指定しないと動かないみたいなので、苦し紛れに入れています。
かなり遅くなっています。
できればG9は制約条件として=0にすればすっきにするのですが。
「ターゲットセル」を指定する必要がなければ、そのようにしてください。

これで実行すれば「変更させるセル」に数値(ロット数)が入ります。

GLPKプログラム

GLPKで動くプログラムも載せていきます。
同じことができます。

manufacuring31.mod
# version 0.2
set WorkingDay; # 工場稼働日付を読み込む
set ProductName; # 製品名を読み込む
param manHourPerLot{ProductName}; # 1ロットの工数
param nLotByProduct{ProductName}; # 製品ごとのロット数
set ManufacturablePeriod  dimen 2; # 生産可能日を読み込む
param manHourByDay{WorkingDay} default 100; # 1日の標準的な工数上限

var assignLot{ManufacturablePeriod} integer, >=0 ; # 生産可能な日のロット数
# 各製品のロット数の合計を合わす
s.t. product1{p in ProductName}: sum{(d,p) in ManufacturablePeriod}assignLot[d,p]==nLotByProduct[p];
# 1日の総工数を超えない
s.t. limitWorkerHour{d in WorkingDay}: sum{(d,p) in ManufacturablePeriod}assignLot[d,p]*manHourPerLot[p]<=manHourByDay[d];

solve;

# 結果を出力
for{d in WorkingDay}{
    printf "%s   総工数 %10.2f\n", d, sum{(d,p) in ManufacturablePeriod}assignLot[d,p]*manHourPerLot[p];
    printf "  製品名 ロット数*ロット当たりの工数\n";
    printf{(d,p) in ManufacturablePeriod: assignLot[d,p]>0} "  %s   %d * %d\n", p, assignLot[d,p], manHourPerLot[p];
}

data;
# 工場稼働日付
set WorkingDay := 1 2 4;
# 製品名と1ロットの工数
param : ProductName : manHourPerLot:=
"製品1"   25
"製品2"   25
"製品3"   20
"製品4"   40
"製品5"   20
;
# 製品ごとのロット数
param : nLotByProduct:=
"製品1"  4
"製品2"  2
"製品3"  1
"製品4"  2
"製品5"  2
;
# 製品名と生産可能日
set ManufacturablePeriod :=
(*, "製品1") 1 2  # 製品1を1 2 日に限定
(*, "製品2") 2 4
(*, "製品3") 1 2
(*, "製品4") 2 4
(*, "製品5") 1 2 4
;
# 1日の工数上限を特別に変えたい場合
param manHourByDay[2] := 110;
end;
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?