1
0

More than 1 year has passed since last update.

駅メモイベントで最適化

Last updated at Posted at 2022-10-19

駅メモで最適化

今の駅メモのイベント。

「材料を集めて美味しいご飯を作るとポイント獲得」のところで、最適化ができそうでした。

ルール概要

TODO:画像を貼る

  • ゲームを進めると秋っぽい食材が手に入る。
    • 薪、栗、皿、魚、きのこ、ぶどう、調味料、あけび、まつたけ
  • 9種類の材料の組み合わせで作る5種類のメニューがある
    • 焼き栗=薪+栗、魚の塩焼き = 薪+栗+魚、etc...
  • メニューを1つ作成すると、材料が1つずつ消費されて、当該メニューに割り当てられたポイントが獲得できる
    • 焼き栗は30ポイント、魚の塩焼き120ポイント、etc...

最適化の定式化

変数を以下のように定義して、

\begin{align}
x_i &= \text{(メニュー$i$を作る個数)}, \\
y_{ij} &= \text{(メニュー$i$が材料$j$を使うなら1)}, \\
z_{j}  &= \text{(材料$j$の個数)}, \\
P_{i}  &= \text{(メニュー$i$を1つ作る時のポイント)},
\end{align}

以下のように定式化できます。

\begin{align}
\max & \sum\limits_{i=1..5} P_i x_i, \\
\mathrm{s.t} \ \  x_i &>=0, \\
                \sum\limits_{i=1..5} x_i y_{ij} &<= z_j \ (j = 1..9)
\end{align}

実行環境

ColaboratoryとPulpで最適化します。↓を読みましょう。
https://www.y-shinno.com/pulp-intro/
よくわかりました。

実装

TeXをいい感じに書くよりも、実装する方が簡単です。

!pip install pulp
import pulp
# 問題の定義
problem = pulp.LpProblem(name="EKIMEMO_2022_Autumn", sense=pulp.LpMaximize)

# 変数の定義
A = pulp.LpVariable(name = "Yakiguri", lowBound = 0, cat="Integer")
B = pulp.LpVariable(name = "Shioyaki", lowBound = 0, cat="Integer")
C = pulp.LpVariable(name = "Kinoko-Jiru", lowBound = 0, cat="Integer")
D = pulp.LpVariable(name = "Moriawase", lowBound = 0, cat="Integer")
E = pulp.LpVariable(name = "Matsutake-Gohan", lowBound = 0, cat="Integer")

# 目的関数(得られるスコア)
problem += 30 * A + 120 * B + 200 * C + 500 * D + 700 * E
  
# 制約条件の定義
problem += A+B+C  +E <= maki ## maki: 材料「薪」の個数
problem += A+B  +D   <= kuri ## kuri: 材料「栗」の個数
problem +=     C  +E <= sara ## sara: (以下同様)
problem +=       D   <= budou 
problem +=   B  +D   <= sakana
problem +=         E <= chomiryo
problem +=     C  +E <= kinoko
problem +=       D   <= akebi
problem +=         E <= matsutake

# 解く
status = problem.solve()
print(pulp.LpStatus[status])

# 結果表示
print("Result")
print("Yakiguri:", A.value())
print("Shioyaki:", B.value())
print("Kinoko-Jiru:", C.value())
print("Moriawase:", D.value())
print("Matsutake-Gohan:", E.value())

UI

https://qiita.com/john-rocky/items/e5802cdd15dc2e34cb84
これを参考に、今持っている材料の個数を入力するためのフォームを作りました。便利ですね。

スクリーンショット 2022-10-19 21.42.41.png

解く

解きましょう
スクリーンショット 2022-10-19 21.45.00.png
解けました。材料足りないので、解がつまらんです。

今後の取り組み

  • Webアプリにする
  • pulpの目的関数や制約を、for文で書く
  • ゲームを頑張って材料を集める
1
0
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
1
0