謝罪 最適化 PuLP

謝罪 最適化

謝罪に関する最適化問題として、以下のような例を考えます。

問題:

ある会社で、顧客への遅延配送により謝罪の手紙を送ることになりました。

手紙を送るべき顧客は複数人いますが、手紙の作成には時間とコストがかかります。

手紙を送るべき顧客の中から、最適な顧客を選び出す問題を考えます。

制約条件:

🔹手紙を送るべき顧客の数は最大でN人までです。
🔹手紙の作成にかかる時間は、各顧客ごとに異なります。
🔹手紙の作成にかかるコストも、各顧客ごとに異なります。
🔹会社は手紙を送ることによるイメージアップの効果を期待しています。
 各顧客にはイメージアップ度合いがあります。

目的:

手紙を送るべき顧客を選ぶことで、以下の条件を最大化することを目指します。

🔹イメージアップ度合いの合計

解法

PuLPを使用してこの問題を解決するPythonコードの例を以下に示します。

このコードでは、PuLPを使用して最適化問題を定義し、制約条件と目的関数を設定しています。

最適化の実行後に、選択された顧客と目的関数の値が表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from pulp import *

# 顧客の情報
customers = [
{"name": "顧客A", "time": 2, "cost": 200, "image": 8},
{"name": "顧客B", "time": 3, "cost": 150, "image": 7},
{"name": "顧客C", "time": 1, "cost": 50, "image": 3},
{"name": "顧客D", "time": 4, "cost": 100, "image": 5},
{"name": "顧客E", "time": 2, "cost": 120, "image": 6}
]

# インデックスのリスト
indices = range(len(customers))

# 最適化問題の定義
prob = LpProblem("Apology Optimization Problem", LpMaximize)

# 変数の定義
selections = LpVariable.dicts("Selection", indices, cat='Binary')

# 目的関数の定義
prob += lpSum([customers[i]["image"] * selections[i] for i in indices])

# 制約条件の定義
prob += lpSum([customers[i]["time"] * selections[i] for i in indices]) <= 6 # 時間制約
prob += lpSum([customers[i]["cost"] * selections[i] for i in indices]) <= 300 # コスト制約

# 最適化の実行
prob.solve()

# 結果の表示
print("最適化結果:")
for i in indices:
if selections[i].varValue == 1:
print(f"{customers[i]['name']}: 送る")

# 目的関数値の表示
print("目的関数値:", value(prob.objective))

コードの詳細な説明を示します。

1. PuLPライブラリをインポートします。
2. 顧客の情報を辞書のリストとして定義します。

 各顧客は名前、時間、コスト、イメージアップ度合いの情報を持っています。

3. インデックスのリストを作成します。

 これは顧客を識別するための番号です。

4. 最適化問題を定義します。

 LpProblemオブジェクトを作成し、問題の名前と最大化することを示すLpMaximizeを指定します。

5. 変数の辞書を定義します。

 LpVariable.dicts()メソッドを使用して、選択変数を作成します。
 各顧客に対してバイナリ変数が作成されます。

6. 目的関数を定義します。

 顧客ごとにイメージアップ度合いと選択変数を掛けて総和を計算し、最大化するように設定します。

7. 制約条件を定義します。顧客ごとに時間制約とコスト制約を設定します。

 時間制約では、顧客ごとの時間と選択変数を掛けて総和が6以下になるようにします。
 同様に、コスト制約では総コストが300以下になるようにします。

8. 最適化を実行します。

 prob.solve()メソッドを呼び出して最適化を実行します。

9. 結果を表示します。

 選択された顧客の名前と「送る」という表示を出力します。
 また、目的関数の値を表示します。

上記のコードを実行すると、最適な顧客の選択と目的関数の値が表示されます。

選ばれた顧客は、手紙を送るべき顧客であり、「送る」と表示されます。

また、目的関数の値は、選択された顧客のイメージアップ度合いの合計です。

結果

コードを実行すると、次のような結果が表示されます。

[実行結果]
最適化結果:
顧客B: 送る
顧客E: 送る
目的関数値: 13.0

この結果は、顧客B顧客Eが手紙を送るべき顧客として選ばれ、目的関数の値(イメージアップ度合いの合計)が13.0であることを示しています。