質問編集履歴

1

質問内容

2020/12/22 06:18

投稿

K.takita
K.takita

スコア14

test CHANGED
@@ -1 +1 @@
1
- False場合の削除について
1
+ プログラムエラーについて
test CHANGED
@@ -1,9 +1,9 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
+ すみません。先ほど投稿した、「Falseの場合削除する」についての質問内容ですが、聞きたかったことと異なっていたため、内容を変えさせていただきます。
4
+
3
5
  以下の作成したプログラムについての質問です。
4
6
 
5
- このプログラムでは各メンバーの希望出勤時刻と、シフトの同時刻を比較し、希望出勤時刻が0, シフトの同時刻が1のときFalse、それ以外のものをTrueで返すプログラムを表しています。
6
-
7
7
  ### 該当のソースコード
8
8
 
9
9
 
@@ -14,6 +14,8 @@
14
14
 
15
15
  import pandas as pd
16
16
 
17
+ from pulp import LpBinary, LpMinimize, LpProblem, LpVariable, lpSum, value
18
+
17
19
 
18
20
 
19
21
  #アルバイトの集合
@@ -52,6 +54,8 @@
52
54
 
53
55
 
54
56
 
57
+
58
+
55
59
  #シフトの一覧(直書き)
56
60
 
57
61
  shift = pd.DataFrame([[0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -68,6 +72,58 @@
68
72
 
69
73
 
70
74
 
75
+ #0:出勤不可のシフトパターン, 1:出勤可能のシフトパターン
76
+
77
+ shiftdaycount = [int(sum(x) > 0) for x in shift.values]
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+ #各シフトの労働時間(直書き)
88
+
89
+ wtime = pd.DataFrame([[0, 0, 0, 0, 0, 0, 0],
90
+
91
+ [9, 9, 9, 9, 9, 9, 9],
92
+
93
+ [3, 3, 3, 3, 3, 3, 3],
94
+
95
+ [3, 3, 3, 3, 3, 3, 3],
96
+
97
+ [3, 3, 3, 3, 3, 3, 3],
98
+
99
+ [6, 6, 6, 6, 6, 6, 6]], index=shiftnumber, columns=day)
100
+
101
+
102
+
103
+ #必要人数
104
+
105
+ need = pd.DataFrame([[2, 2, 2, 2, 2, 2, 2, 2, 2]], index=day, columns=time)
106
+
107
+
108
+
109
+ #希望出勤日
110
+
111
+ kibou = pd.DataFrame([[1, 1, 1, 1, 1, 1, 1],
112
+
113
+ [1, 1, 1, 1, 1, 1, 1],
114
+
115
+ [1, 1, 1, 1, 1, 1, 1],
116
+
117
+ [1, 1, 1, 1, 1, 1, 1],
118
+
119
+ [0, 0, 0, 0, 0, 0, 0]], index=member, columns=day)
120
+
121
+
122
+
123
+
124
+
125
+
126
+
71
127
 
72
128
 
73
129
  #時間を考慮したデータ
@@ -84,9 +140,147 @@
84
140
 
85
141
  [0, 0, 0, 0, 0, 0, 0, 0, 0]], index=kibou.iloc[:,0], columns=time)
86
142
 
143
+
144
+
145
+
146
+
147
+
148
+
87
-
149
+ #for t in range(time.size):
150
+
88
-
151
+ # for s in range(n_shiftnumber):
152
+
89
- #希望出勤時刻が0, シフトの同時刻が1のときFalse、その他をTrueで返す
153
+ # for m in range(member.size):
154
+
155
+ # shift.iloc[s,t] <= kiboutime1.iloc[m,t]
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+ #各メンバーの時給
168
+
169
+ jikyu = pd.DataFrame([[900, 900, 900, 900, 900, 900, 900],
170
+
171
+ [900, 900, 900, 900, 900, 900, 900],
172
+
173
+ [900, 900, 900, 900, 900, 900, 900],
174
+
175
+ [900, 900, 900, 900, 900, 900, 900],
176
+
177
+ [900, 900, 900, 900, 900, 900, 900]], index=member, columns=day)
178
+
179
+
180
+
181
+ #1日の人件費
182
+
183
+ jinkenhi = pd.DataFrame([[16200],
184
+
185
+ [16200],
186
+
187
+ [16200],
188
+
189
+ [16200],
190
+
191
+ [16200],
192
+
193
+ [16200],
194
+
195
+ [16200]], index=day)
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+ #モデルの作成
204
+
205
+ prob = LpProblem(sense=LpMinimize)
206
+
207
+
208
+
209
+ #変数
210
+
211
+ X = LpVariable.dicts('X', ([m for m in range(member.size)], [d for d in range(day.size)], [s for s in range(n_shiftnumber)]), 0, 1, 'Integer')
212
+
213
+
214
+
215
+
216
+
217
+ #目的関数
218
+
219
+ prob += kibou.values.sum() - lpSum(shiftdaycount[s] * X[m][d][s] for s in range(n_shiftnumber) for d in range(day.size) for m in range(member.size))
220
+
221
+
222
+
223
+ #制約条件
224
+
225
+ #(制約1)
226
+
227
+ for m in range(member.size):
228
+
229
+ #希望出勤日数
230
+
231
+ ks = kibou.iloc[m].sum()
232
+
233
+ #実際に働いた日数
234
+
235
+ actual = lpSum(shiftdaycount[s] * X[m][d][s] for s in range(n_shiftnumber) for d in range(day.size))
236
+
237
+ #(制約1)実際に働いた日数が希望出勤日数を超えない制約
238
+
239
+ prob += actual <= ks
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+ #(制約2)必要最低人数を満たす制約
248
+
249
+ for d in range(day.size):
250
+
251
+ for t in range(time.size):
252
+
253
+ prob += lpSum(shift.values[s][t] * X[m][d][s] for s in range(n_shiftnumber) for m in range(member.size) ) >= need.iloc[d, t]
254
+
255
+
256
+
257
+ #(制約4)各メンバーが1日に取りうるシフトは必ず1つ
258
+
259
+ for m in range(member.size):
260
+
261
+ for d in range(day.size):
262
+
263
+ prob += lpSum(X[m][d][s] for s in range(n_shiftnumber)) == 1
264
+
265
+
266
+
267
+ #(制約5)人件費を超えない
268
+
269
+ for d in range(day.size):
270
+
271
+ prob += lpSum(jikyu.iloc[m, d] * wtime.iloc[s, d] * X[m][d][s] for m in range(member.size) for s in range(n_shiftnumber) ) <= jinkenhi.iloc[d]
272
+
273
+
274
+
275
+ #(制約6)6日以上の連続勤務を禁止する
276
+
277
+ for m in range(member.size):
278
+
279
+ prob += lpSum(shiftdaycount[s] * X[m][d][s] for s in range(n_shiftnumber) for d in range(day.size)) <= 6
280
+
281
+
282
+
283
+ #(制約7)
90
284
 
91
285
  for t in range(time.size):
92
286
 
@@ -94,16 +288,58 @@
94
288
 
95
289
  for m in range(member.size):
96
290
 
97
- shift.iloc[s,t] <= kiboutime1.iloc[m,t]
291
+ prob += shift.iloc[s,t] <= kiboutime1.iloc[m,t]
292
+
293
+
294
+
295
+
296
+
297
+ prob.solve()
298
+
299
+
300
+
301
+
302
+
303
+ scheduling = pd.DataFrame(index=member, columns=day)
304
+
305
+ for m in range(member.size):
306
+
307
+ for d in range(day.size):
308
+
309
+ for s in range(n_shiftnumber):
310
+
311
+ if X[m][d][s].value() == 1:
312
+
313
+ scheduling.iloc[m, d] = shiftnumber[s]
98
314
 
99
315
 
100
316
 
101
317
 
102
318
 
319
+ scheduling.to_csv("scheduling.csv")
320
+
321
+
322
+
103
323
  ```
104
324
 
105
-
325
+ (制約7)のところで、各メンバーの希望出勤時間とシフトパターンの同時刻部分を比較しています。シフトの時刻は、同時刻の希望出勤時間以下となる制約(希望出勤時間が0の時、シフトの同時刻は0をとり、その他の場合は0または1をとる)を表しています。
106
-
326
+
107
- この結果のFalseを削除したいのですが、どのようにすればよいのでしょうか
327
+ 手書きはありますが、やりたことイメージは以下の通り
328
+
108
-
329
+ ![イメージ説明](498ca2e8dd3dbd4948d5407225f7c06b.jpeg)
330
+
331
+ しかし以下のようなエラーメッセージが出てきてしまいます。
332
+
333
+ ### 発生してるエラーメッセージ
334
+
335
+ ```python
336
+
337
+ TypeError: Can only add LpConstraintVar, LpConstraint, LpAffineExpression or True objects
338
+
339
+ ```
340
+
341
+ (制約7)より前のものは、正しく動いていることが確認できているため、(制約7)の部分でエラーが起きていると思うのですが、どのように直したらいいか、または、別のやり方があるのかわからない状態です。
342
+
343
+ 一方的な質問ですがご教授いただきたいです。
344
+
109
- ご教授いただけると幸いです。よろしくお願いします。
345
+ よろしくお願いいたします。