看護師スケジュール作成問題 PuLP

看護師スケジュール作成問題

医療に関する最適化問題の例として、病院の看護師スケジュール作成問題を考えてみましょう。

この問題では、病院で働く看護師の勤務シフトをスケジュールする必要があります。

スケジュールは、各看護師の希望や能力に応じて、労働法や病院の規則に準拠しなければなりません。


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from pulp import *

# ①条件を定義する
# 看護師の数
num_nurses = 5

# シフトの数
num_shifts = 3

# 各シフトで必要な看護師の数
shift_requirements = [2, 1, 2]

# 看護師の希望を表す二次元配列。0は不可能、1は可能。
# 希望は、勤務シフトを表すインデックスで表されます。
# たとえば、nurse_preferences[0][1] == 1は、看護師0が2番目のシフトを希望していることを示します。
nurse_preferences = [[0, 1, 1], [1, 0, 1], [1, 1, 0], [1, 1, 1], [0, 1, 0]]

# ②問題を定義する
problem = LpProblem("Nurse Scheduling", LpMinimize)

# ③変数を作成する
shifts = LpVariable.dicts("Shift", ((n, s) for n in range(num_nurses) for s in range(num_shifts)), cat='Binary')

# ④目的関数を設定する
problem += lpSum([shifts[(n, s)] for n in range(num_nurses) for s in range(num_shifts)])

# ⑤制約条件を設定する
for s in range(num_shifts):
problem += lpSum([shifts[(n, s)] for n in range(num_nurses)]) >= shift_requirements[s]

for n in range(num_nurses):
problem += lpSum([shifts[(n, s)] for s in range(num_shifts)]) == 1

for n in range(num_nurses):
for s in range(num_shifts):
if nurse_preferences[n][s] == 0:
problem += shifts[(n, s)] == 0

# ⑥問題を解く
status = problem.solve()

# ⑦結果を出力する
print("ステータス:", LpStatus[status])

for n in range(num_nurses):
for s in range(num_shifts):
if value(shifts[(n, s)]) == 1:
print("看護師{}は、シフト{}に割り当てられました".format(n, s))

① 条件を定義する

最初に、看護師の数、シフトの数、各シフトで必要な看護師の数、および各看護師のシフト希望を表す二次元配列を定義します。

② 問題を定義する

PuLPの LpProblem() 関数を使用して、問題を定義します。

この問題は、看護師のスケジュール作成を目的としています。

PuLPの LpMinimize モードを使用して、最小化問題を解決します。

③ 変数を作成する

PuLPの LpVariable.dicts() 関数を使用して、shifts 変数を作成します。

各変数は、看護師があるシフトに割り当てられる場合は1、そうでない場合は0を取るバイナリ変数です。

④ 目的関数を設定する

PuLPの lpSum() 関数を使用して、目的関数を設定します。

目的関数は、スケジュールに割り当てられたシフトの数を最小化することです。

⑤ 制約条件を設定する

PuLPの += 演算子を使用して、制約条件を設定します。

最低限必要な看護師数の制約条件、各看護師が1つのシフトにしか割り当てられない制約条件、および各看護師がシフト希望に従って割り当てられる制約条件を設定します。

⑥ 問題を解く

PuLPの solve() 関数を使用して、問題を解決します。

最適解が見つかれば、そのステータスが返されます。

⑦ 結果を出力する

最後に、割り当てられた各看護師のシフトを表示します。

看護師の番号とシフトの番号が表示されます。


このコードを実行すると次のような結果が出力されます。

[実行結果]
ステータス: Optimal
看護師0は、シフト2に割り当てられました
看護師1は、シフト2に割り当てられました
看護師2は、シフト0に割り当てられました
看護師3は、シフト0に割り当てられました
看護師4は、シフト1に割り当てられました

ステータスが Optimalであることが示されています。

これは、問題が最適解を見つけることができたことを示しています。

次に、各看護師がどのシフトに割り当てられたかが表示されます。

例えば、看護師0は2番目のシフトに割り当てられました。

これは、制約条件目的関数を満たし、最適なスケジュールに割り当てられたことを意味します。

このプログラムによって、病院の看護師スケジュール作成問題が解決され、最適なスケジュールが得られました。