2019年8月25日日曜日

Python Itertools


5個の月曜日の公休のうち、4個だけ公休を取るという制約を考えてみましょう。
これを論理演算子だけで制約せよ! という例題をやってみましょう。

次のAB)を実現することで、実装可能です。


A)Σ~公休>=1ですから、~公休 のORをとってAssertすればよいです。
B)5個から2個取る全ての組み合わせで2個とも~公休は禁止 →~(~公休 & ~公休) →公休 | 公休 となりますから、全ての組み合わせでORAssertすればよいです。
 

 
5個から2個取る全ての組合せを列挙するのが面倒ですが、それは、Python Itertoolsに任せればよいです。Itertools.combinationsが全ての組み合わせを列挙してくれます。


面倒な仕様にも思えますが、次のように僅か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 件のコメント:

コメントを投稿