5個の月曜日の公休のうち、4個だけ公休を取るという制約を考えてみましょう。
これを論理演算子だけで制約せよ! という例題をやってみましょう。
次のA)B)を実現することで、実装可能です。
■A)Σ~公休>=1ですから、~公休 のORをとってAssertすればよいです。
■B)5個から2個取る全ての組み合わせで2個とも~公休は禁止 →~(~公休 & ~公休) →公休 | 公休 となりますから、全ての組み合わせでORをAssertすればよいです。
■A)Σ~公休>=1ですから、~公休 のORをとってAssertすればよいです。
■B)5個から2個取る全ての組み合わせで2個とも~公休は禁止 →~(~公休 & ~公休) →公休 | 公休 となりますから、全ての組み合わせでORをAssertすればよいです。
5個から2個取る全ての組合せを列挙するのが面倒ですが、それは、Python Itertoolsに任せればよいです。Itertools.combinationsが全ての組み合わせを列挙してくれます。
面倒な仕様にも思えますが、次のように僅か14行で記述できました。
面倒な仕様にも思えますが、次のように僅か14行で記述できました。
import sc3
import itertools
for person in 全スタッフ:
vlist=[]
s='言語公休回数'+' '+staffdef[person]+'\n'
for day in 月:
v=sc3.GetShiftVar(person,day,'公休')
vlist.append(v)
sc3.AddHard(vlist[0] | vlist[1] | vlist[2] | vlist[3] | vlist[4],s)#互いに等価な制約
for v in itertools.combinations(vlist,2):
sc3.AddHard(v[0] | v[1],s)

0 件のコメント:
コメントを投稿