ページ移動:JavaScriptを有効にして下さい!
15.連続勤務日数の制限

勤務が長期間連続することに抑制を掛けます。

方式:

割り当てられたシフト勤務(変化するセル)において、連続する勤務(=休み以外)の個数を調べます。
ここでは、連続する勤務の個数とは、
  4連続の勤務の個数(4連続勤務を1個とする)
  5連続の勤務の個数(同上)
  6連続以上の勤務の個数(同上)
とします。
それぞれの個数に重み(連続数が多いほど抑制したいので、その重みを大きくする)を掛けた値(連 続休み個数値)を最小にするように均等再配置を行います。

ただし、他の条件もも最小化しないといけないので、

勤務日数の分散+連続休み個数値+連続勤務個数値

目標値(最 小化セル)の値とします。
(それぞれの重みは必要に応じて設定)

具体的な数式例

連続勤務数の求め方

連続休み数と同じように数式で求めるのは、少々、面倒です。
(配列数式を使用しても、いくつかの補助表が必要になりそうです。)

よって、ここでは、VBAを使用してユーザー定義関 数を作成します。

関数の仕様

  文字列中の中から指定文字列がいくつ含まれるかを正規表現で指定して求める。

書式; MyRegCount(Src , Pattern)

  Src   : 対象文字列
  Pattern: 検索対象文字列(正規表現

戻り値:連続勤務の個数

例: 正規表現の詳しい記述方法は右を参照 - 正規表現記述例

下の例で、「0」以外の4個の数字が連続している個数を求めてみます。


  0011110022222003333

求めるのは、ピンク色の文字列の個数(2個)。

正規表現で表すと [^0]{4}
  ^:否定  [ ]:択一 [^0]:0以外の1文字
  {4}:4個連続( {4,}カンマを付けると4個以上となり、{4,6}のようにすると、4個以上6個以内となる)

ただし、このままでは5個連続する 22222 の中にも4個の連続する0以外の数字があるため、不必要にマッチすることになります。
よって、もう少し条件を詳しく書くと、

「前後が「0」で、その間に4個の「0」以外の数字が連続する」となります。
正規表現では、 0[^0]{4}0  と書けます。

ところが、例の「3333」の右端は「0」に接していないので、このままでは正規表現の条件を満たしません。
よって、元の文字列の両端に「0」を付加した 000111100222220033330  を対象文字列とします。

下図の例では、セルK53の文字列から「0」以外の4個連続する文字列の個数を求めるには、

  MyRegCount("0" & K53 & "0","0[^0]{4}0")

となります。(下図の例では、正規表現の個数部分を見出しとして可変にしています。)

なお、ここでは、連続休み数も同関数を使用して書き換えています。
考え方は連続勤務数と同じ。ただし、付加する両端の文字列は「0」以外の任意の数字(ここでは「9」)


重みについて

最小化すべき値は、

勤務日数の分散計 = 各勤務日数の分散値に重みを掛けて合計
連続休み日数の分散計 = 2連休、3連休、4連休以上の分散値に重みを掛けて合計
連続勤務日数の分散計 = 4連勤、5連勤、6連勤以上の分散値に重みを掛けて合計

の、さらに、合計 となっています。

よって、おおよそ、全てが最小に近づくようになりますが、
場合によっては、勤務日数にバラツキがでたり、5連勤が発生したりする場合があります。

勤務日数を重点的に均等にしたい場合は、その部分の重みを大きくしてください。

  下図の例では、黒枠内の数値を変更します。
  セルR60 1 → 10 のようにすると、勤務日数の均等化が最重要ポイントとなる。

連続勤務数を制限したい場合は、5連勤、6連勤部分の重みを大きくします。
  セルAA60 0.2→5 、セルAB60 1→10 のようにすると、連続勤務日数の抑制が最重要ポイントとなります。 


ユーザー定義関数

Option Explicit

Dim re As New RegExp '正規表現オブジェクト

Function MyRegCount(Src As String, Pattern As String) As Integer
'
' 正規表現による検索
'
' 入力
'  Src :検索対象文字列
'  Pattern:検索正規表現パターン
'
' 戻り値 :見つかった個数
'
	MyRegCount = 0
 
	Dim reMatch As MatchCollection 'マッチ結果格納用オブジェクト
 
	With re
		.Pattern = Pattern
		.IgnoreCase = True '大小文字の区別無し
		.Global = True '文字列全体を検索
		If re.test(Src) Then 'テスト
			Set reMatch = .Execute(Src) '発見
			MyRegCount = reMatch.Count '個数セット
		End If
	End With<
 
End Function

正規表現オブジェクト「RegExp」を使用するため、「Microsoft VBScript Regular Expressions」の参照設定が 必要です。


作成例

単純割り振り


連続休み・勤務個数抑制 - 2連休、2連勤以内に収まった!

2週間シフト表で見ると、もう少し、よくわかる

抑制無し - 4連休と6連勤が発生


連続休み・勤務個数抑制 - 2連休、5連勤以内に収まった


計算上の工夫

「変化させるセル」の値が変わると、各種の集計値も再計算されます。
ソルバーで実行中も、見た目の集計値は変化しないようでも、内部的には再計算を行っているように感じます。
(集計の式がある場合と無い場合では、ソルバーの完了までの時間が異なる)

ここでは、上図の青枠のような「集計実行」スイッチ を設け、TRUEの場合のみ集計(集計表、連続休み数、連続勤務数)の計算を行うようにします。
すなわち、ソルバーの実行前に「集計実行」をFALSEにして集計の再計算を行わないようにし、ソルバーが終わった後にTRUEにして、均等再配置を実行 するようにしています。


注意

連続休み/連続勤務の抑制は、あくまでも努力目標で す。
場合によっては、5連休、6連勤が発生することもあります。
その場合は、重みを調整して、再実行を繰り返してください。


ページ移動:JavaScriptを有効にして下さい!

関連

×
PageTop