作成: 日大生産工 MA 大前
これは、大前研究室の卒業研究テーマの学習資料として作成されたものです。他のゼミ生がこのページを参考にして卒業研究を行う場合は、必ず事前に相談してください。異なる研究室なのに、同じテーマが卒業研究概要集に並んでいると、問題になるかもしれません。
# google collabを利用している人は、はじめに以下を実行してください。
!pip install pulp
以下の問題を考えてみましょう。
このような状況のとき、製品XとYをいくつ作ると、売り上げが最大となるか? ただし、作った製品はすべて売れるものとします。
状況がややこしいので、
というパターンを調べてみます。
x = 10 # 製品Xの作成数
y = 20 # 製品Yの作成数
N_A = 1*x + 6*y # 素材Aの使用数
N_B = 5*x + 4*y # 素材Bの使用数
TotalValue = 100*x + 200*y # 売上(製品Xが1つにつき100円、製品Yが1つにつき200円)
print("製品Xの作成数: ", x, " 個")
print("製品Yの作成数: ", y, " 個")
print("素材Aの使用数: ", N_A, " 個(上限100)")
print("素材Bの使用数: ", N_B, " 個(上限200)")
print("売り上げ: ", TotalValue, " 円(← 素材Aの使用数がオーバーしているので、実現不可能)")
となりました。5000円の売り上げとなるようですが、素材Aを130個使っており、上限を超えています。つまり、「製品Xを10個、製品Yを20個作る」実現不可能であることがわかります。
これを踏まえて、改善を考えてみます。素材Aがオーバーするため、素材Aの使用数を下げなければなりません。素材Aは、製品Yを作成するときに6個も消費してしまうようです。そのため、製品Yの作成数を7個だけ減らしてみましょう。具体的には、
としてみます。
x = 10 # 製品Xの作成数
y = 13 # 製品Yの作成数
N_A = 1*x + 6*y # 素材Aの使用数
N_B = 5*x + 4*y # 素材Bの使用数
TotalValue = 100*x + 200*y # 売上
print("製品Xの作成数: ", x, " 個")
print("製品Yの作成数: ", y, " 個")
print("素材Aの使用数: ", N_A, " 個(上限100)")
print("素材Bの使用数: ", N_B, " 個(上限200)")
print("売り上げ: ", TotalValue, " 円")
素材Aの使用数が、無事に100個未満になりました。でも、素材Aはまだちょっと余裕があります。製品Yを減らしすぎたのかもしれません。もうちょっと作れば、3600円よりも売上が上がりそうです。そのため、製品Yを少し増やし、
にしてみましょう。
x = 10 # 製品Xの作成数
y = 15 # 製品Yの作成数
N_A = 1*x + 6*y # 素材Aの使用数
N_B = 5*x + 4*y # 素材Bの使用数
TotalValue = 100*x + 200*y # 売上
print("製品Xの作成数: ", x, " 個")
print("製品Yの作成数: ", y, " 個")
print("素材Aの使用数: ", N_A, " 個(上限100)")
print("素材Bの使用数: ", N_B, " 個(上限200)")
print("売り上げ: ", TotalValue, " 円")
素材Aの使用数がぴったり100になりました。売上も4000円までアップしました。前よりは良さそうです。 しかし、素材Bがだいぶ余っています。製品Xが10個、製品Yが15個というのは、本当に最適でしょうか?
だんだんわからなくなってきました。ここらでわかるように、このように数字を当てはめて考えていくということは、ちょっと非効率な気がします。
そこで登場するのが、整数計画法という手法です。この方法は少しややこしいので解説は省略しますが、
を設定することで、最適な答えを教えてくれる手法となります。問題そのものは整数計画問題、解き方を整数計画法と呼びます。
これを考えるため、はじめに、以下のように変数を定義します。
この際、今回の事例でいえば、目的関数と制約条件は以下のように定義できます。
この条件で整数計画問題を解くコードは、下記となります。
from pulp import LpProblem, LpMaximize, LpVariable, value
Prb = LpProblem(sense=LpMaximize) # 最大化を考えたい(LpMaximize)
X = LpVariable('X', cat="Integer", lowBound=0) # Xは0以上の整数(制約3)
Y = LpVariable('Y', cat="Integer", lowBound=0) # Yは0以上の整数(制約3)
Prb += 100*X + 200*Y # 目的関数(最大化したい指標)
Prb += 1*X + 6*Y <= 100 # 素材Aの上限(制約1)
Prb += 5*X + 4*Y <= 200 # 素材Bの上限(制約2)
Prb.solve()
print("製品Xの作成数: ", value(X), "個")
print("製品Yの作成数: ", value(Y), "個")
製品Xを31個、製品Yを11個作ると、制約を守りながら、売上が最大化されるという結果となりました。これだけの数を作成して、素材の使用数を違反しないのか、チェックしてみます。
x = 31 # 製品Xの作成数
y = 11 # 製品Yの作成数
N_A = 1*x + 6*y # 素材Aの使用数
N_B = 5*x + 4*y # 素材Bの使用数
TotalValue = 100*x + 200*y # 売上
print("製品Xの作成数: ", x, " 個")
print("製品Yの作成数: ", y, " 個")
print("素材Aの使用数: ", N_A, " 個(上限100)")
print("素材Bの使用数: ", N_B, " 個(上限200)")
print("売り上げ: ", TotalValue, " 円")
素材AもBも、ギリギリまで使用できていることがわかります。また、売上も、今までで一番大きいことがわかりました(この結果のみで売上が最大であると主張できる証拠はありませんが、実際には5300円が最大となります)。
(1) 今回は、製品X、製品Y、素材A、素材Bを扱いました。これを、あなたが思う実際の製品と素材にしてください。
例えば
として、
などです。学習が目的なので、無理矢理になっても構いません。製品と素材の種類は2より大きくてもokです。
(2) 上記について、素材の上限と、製品を作るために必要な素材数を考えてください。
(3) 上記について、製品の販売価格を決めてください。
(4) 目的関数と制約を、数式で表現してください。
(5) 上記の条件で、最適な製造数を、プログラムにより求めてください。
1章 はじめに:(文章量の比率: 15%)
2章 整数計画問題:(文章量の比率: 30%)
3章 実験:(文章量の比率: 40%)
3.1節 概要:
3.2節 結果と考察:
4章 おわりに:(文章量の比率: 15%)
参考文献:
参考にした資料を、2〜3件記載してください。以下、書き方の例です。
本文中で引用する場合は「大前らはXXXを実施している [1]。また、〜」のように、どこで引用したのか明白にしてください。