vectorの活用法

例として、

2週連続深夜出勤はしない

という制約を書くことを考えてみましょう。休日の定義は、その週での週末休み(土日)のほか、祝日も含まれるとします。
この実装を少し考えると、単純にはいかないことに気づくと思います。

ある週で、一回でも休日深夜出勤をすると、次の週では、深夜出勤は不可ですから、週に一回以上休日出勤という制約と、2週連続という制約と二つに分けて考えることにします。また、先月の週からの連続も考えてなくてはいけませんので、先月一週間分のデータ取り込みが必要になります。

以上を考慮してコーディングしたのが次です。

for (スキル in スキルclass){//職能毎に
        for (人 in スキル){//そのスキルに属する人について
                vector V週;
                for (週 in 週class){//週ごとに
                        vector V;
                        for(day in 週){
                                if (day in 休診日){
                                        V.push_back(X[人][day][S]);//■■<ーーこちらから追加      
                                }
                        }
                        V週.push_back($Or(V));//一つでも休日深夜勤務がある
                
                        if (V週.size()>=3){//3週溜ったら
                                V週.pop_front();// こちらから捨てる<ーー■■■
                        }
                        if (V週.size()==2){//2週溜れば今月なので
                        
                                $Inv($And(V週));//制約してよい。2週連続の休日深夜勤務禁止
                        }
                }
        }
}

全スタッフをprintすると、大変なので、1人に絞って様子を見ました。

for (スキル in スキルclass){//職能毎に
	for (人 in スキル){//そのスキルに属する人について
		vector V週;
		for (週 in 週class){//週ごとに
			vector V;
			for(day in 週){
				if (day in 休診日){
					V.push_back(X[人][day][S]);//■■<=こちらから追加
					print(day);
				}
			}
			V週.push_back($Or(V));//一つでも休日深夜勤務がある
		
			if (V週.size()>=3){//3週溜ったら
				if (人==3交代深準型スタッフ2){
					print("pop_front前 ",スキル,週,V週,V);
				}
				V週.pop_front();// こちらから<=■■■
			}
			if (V週.size()==2){//2週溜れば今月なので
				if (人==3交代深準型スタッフ2){
					print("制約時 ",スキル,週,V週,V);
				}
				$Inv($And(V週));//制約してよい。2週連続の休日深夜勤務禁止
			}
		}
	}
}

以下が、そのログなのですが、push_back,pop_frontの動作が確認できるのではないでしょうか?

なお、上で使用したのは、以下の定義です。

さて、問題は、確認方法です。制約は、禁止なので、いつも画面に出てくる訳ではありません。この制約で良さそうだということは、上のprint文による検証で推測可能ですが、最終的には、現実の解で見る必要があります。
目視でチェックも疲れるので、やはりスクリプトでチェックしてみましょう。


[Prev] [Next] [Index] [Home]