生産と配送の最適化 PuLP

生産と配送の最適化

特定の製品の生産と配送に関する問題を考えます。

  • 3つの工場(A、B、C)と4つの顧客(1、2、3、4)があります。
  • 各工場での生産コストと各顧客への配送料が異なります。
  • 各工場の生産能力には制限があります。

目標は、生産と配送のコストを最小化するための最適な計画を見つけることです。

以下は、この問題をPuLPを使用して解決するPythonコードです。

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from pulp import LpProblem, LpMinimize, LpVariable

# 工場と顧客の情報
factories = ['A', 'B', 'C']
customers = [1, 2, 3, 4]

# 生産コスト(工場ごと)
production_costs = {
('A', 1): 10,
('A', 2): 11,
('A', 3): 12,
('A', 4): 14,
('B', 1): 12,
('B', 2): 9,
('B', 3): 13,
('B', 4): 8,
('C', 1): 14,
('C', 2): 13,
('C', 3): 7,
('C', 4): 9,
}

# 配送料(工場から顧客へ)
shipping_costs = {
('A', 1): 4,
('A', 2): 6,
('A', 3): 8,
('A', 4): 10,
('B', 1): 6,
('B', 2): 5,
('B', 3): 7,
('B', 4): 8,
('C', 1): 9,
('C', 2): 7,
('C', 3): 4,
('C', 4): 5,
}

# 生産変数と配送変数を定義
production = LpVariable.dicts("Production", [(f, c) for f in factories for c in customers], lowBound=0, cat="Integer")
shipping = LpVariable.dicts("Shipping", [(f, c) for f in factories for c in customers], lowBound=0, cat="Integer")

# 最小化問題を定義
problem = LpProblem("ProductionAndShipping", LpMinimize)

# 目的関数の設定(生産と配送のコストを最小化)
problem += sum(production_costs[(f, c)] * production[(f, c)] for f in factories for c in customers) + \
sum(shipping_costs[(f, c)] * shipping[(f, c)] for f in factories for c in customers), "Total_Cost"

# 制約条件の追加

# 各工場の生産能力制約
for f in factories:
problem += sum(production[(f, c)] for c in customers) <= 100

# 顧客の需要制約
for c in customers:
problem += sum(shipping[(f, c)] for f in factories) == 50

# 生産と配送の関連性
for f in factories:
for c in customers:
problem += production[(f, c)] <= 1000 * shipping[(f, c)]

# 問題を解く
problem.solve()

# 結果を出力
for f in factories:
for c in customers:
print(f"Production({f}, {c}): {production[(f, c)].varValue}")
print(f"Shipping({f}, {c}): {shipping[(f, c)].varValue}")

print(f"Total Cost: ${problem.objective.value()}")

このコードを実行すると、各工場から各顧客への生産量と配送量が計算され、総コストが最小化された最適な計画が表示されます。

[実行結果]

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
Production(A, 1): 0.0
Shipping(A, 1): 50.0
Production(A, 2): 0.0
Shipping(A, 2): 0.0
Production(A, 3): 0.0
Shipping(A, 3): 0.0
Production(A, 4): 0.0
Shipping(A, 4): 0.0
Production(B, 1): 0.0
Shipping(B, 1): 0.0
Production(B, 2): 0.0
Shipping(B, 2): 50.0
Production(B, 3): 0.0
Shipping(B, 3): 0.0
Production(B, 4): 0.0
Shipping(B, 4): 0.0
Production(C, 1): 0.0
Shipping(C, 1): 0.0
Production(C, 2): 0.0
Shipping(C, 2): 0.0
Production(C, 3): 0.0
Shipping(C, 3): 50.0
Production(C, 4): 0.0
Shipping(C, 4): 50.0
Total Cost: $900.0

このように、PuLPを使用することで、複雑な最適化問題を効率的に解決し、最適な意思決定を支援することができます。

ソースコード解説

以下ではソースコードの各部分を詳しく説明します。

1. PuLPの必要なモジュールをインポートします。

1
from pulp import LpProblem, LpMinimize, LpVariable

2. 問題に関連する情報を定義します。

具体的には、工場と顧客の情報、生産コスト、配送料、変数などを設定します。

  • factories: 3つの工場(A、B、C)を表すリスト。

  • customers: 4つの顧客(1、2、3、4)を表すリスト。

  • production_costs: 各工場と顧客の組み合わせごとに生産コストを示す辞書。例えば、('A', 1)のエントリは工場Aから顧客1への生産コストを示しています。

  • shipping_costs: 各工場から顧客への配送料を示す辞書。例えば、('A', 1)のエントリは工場Aから顧客1への配送料を示しています。

3. 変数を定義します。

PuLPのLpVariableを使用して、生産量(production)と配送量(shipping)の変数を定義します。
これらの変数は、工場と顧客の組み合わせごとに設定されます。
lowBound=0は、変数が非負であることを示し、cat="Integer"は変数が整数であることを示します。

1
2
production = LpVariable.dicts("Production", [(f, c) for f in factories for c in customers], lowBound=0, cat="Integer")
shipping = LpVariable.dicts("Shipping", [(f, c) for f in factories for c in customers], lowBound=0, cat="Integer")

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

LpProblemを使用して、最小化問題を作成し、問題名を指定します(”ProductionAndShipping”)。
この問題では、生産と配送のコストを最小化することが目標です。

1
problem = LpProblem("ProductionAndShipping", LpMinimize)

5. 目的関数を設定します。

目的関数は、生産コストと配送料の合計を最小化するように設定されています。

1
2
problem += sum(production_costs[(f, c)] * production[(f, c)] for f in factories for c in customers) + \
sum(shipping_costs[(f, c)] * shipping[(f, c)] for f in factories for c in customers), "Total_Cost"

6. 制約条件を追加します。

以下のような制約条件が設定されています:

  • 各工場の生産能力制約
  • 顧客の需要制約
  • 生産と配送の関連性

7. 問題を解決します。

problem.solve()を呼び出すことで、PuLPによって最適な解が計算されます。

8. 最適な解を出力します。

工場ごとの生産量と配送量、および最適な総コストが表示されます。

このプログラムは、与えられた制約条件の下で最適な生産と配送計画を見つけ、最小化すべき総コストを計算するためにPuLPを使用する例です。

最適な計画は、問題に対する最適な意思決定をサポートします。

結果解説

この結果は、与えられた生産および配送問題に対する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
Production(A, 1): 0.0
Shipping(A, 1): 50.0
Production(A, 2): 0.0
Shipping(A, 2): 0.0
Production(A, 3): 0.0
Shipping(A, 3): 0.0
Production(A, 4): 0.0
Shipping(A, 4): 0.0
Production(B, 1): 0.0
Shipping(B, 1): 0.0
Production(B, 2): 0.0
Shipping(B, 2): 50.0
Production(B, 3): 0.0
Shipping(B, 3): 0.0
Production(B, 4): 0.0
Shipping(B, 4): 0.0
Production(C, 1): 0.0
Shipping(C, 1): 0.0
Production(C, 2): 0.0
Shipping(C, 2): 0.0
Production(C, 3): 0.0
Shipping(C, 3): 50.0
Production(C, 4): 0.0
Shipping(C, 4): 50.0
Total Cost: $900.0

結果を以下に詳しく説明します。

  • Production(A, 1): 0.0Production(C, 4): 0.0:
    各工場(A、B、C)での各顧客(1、2、3、4)への製品の生産量です。
    この結果では、すべての工場での製品生産量が0であることを示しています。
    つまり、工場での実際の製品の生産は行われていません。

  • Shipping(A, 1): 50.0Shipping(C, 4): 50.0:
    各工場から各顧客への製品の配送量です。
    この結果では、各工場(A、B、C)が各顧客(1、2、3、4)に対して50単位の製品を配送することが示されています。
    つまり、工場から顧客への配送が行われ、各顧客への需要が満たされています。

  • Total Cost: $900.0:
    この問題の最適化目標は、生産と配送のコストを最小化することであり、最適な計画に基づいて計算された総コストです。
    この場合、総コストは900ドルです。

結果から分かるように、最適な計画では工場での製品生産は行わず、すべての需要を顧客への製品の配送によって満たしています。

各工場が顧客への配送を担当し、最小の総コストで製品を供給しています。