結論から言うと殆ど変わりませんでした。
下が実行中の様子です。Solver2がSIMD化していないアンローリングコード、Solver3がSIMD化しているコードです。8weeksのインスタンスで50万ノード程度の規模になります。どちらも1ms程度で増減していますが、ほぼ同じ結果となりました。
恐らくは、データが不揃いであり、データフェッチの部分で律速しているのだと思います。
結論から言うと殆ど変わりませんでした。
下が実行中の様子です。Solver2がSIMD化していないアンローリングコード、Solver3がSIMD化しているコードです。8weeksのインスタンスで50万ノード程度の規模になります。どちらも1ms程度で増減していますが、ほぼ同じ結果となりました。
恐らくは、データが不揃いであり、データフェッチの部分で律速しているのだと思います。
マニュアルでアンローリングしたコードを逆アセンブルしてみると、SIMD化していないことに気づきました。
モダンなC++では、下記のような書き方が出来るようですが、私のコードはそこまで洗練されていません。
https://proc-cpuinfo.fixstars.com/2022/12/loop-unroll-in-modern-cpp/
AVX2だと、単精度で8演算が同時に可能なので、8WEEKSに取り掛かる前にさらにSIMDによる高速化を検討します。具体的には、以下のような処理をします。
SIMD 演算で if 文の並列化 - その1 - - kawa0810 のブログ (hateblo.jp)
データフェッチが不揃いなので、ネックは、データフェッチ自体にあります。なので、どれだけ効果があるのかは、現時点では不明です。
また、4Weeksに関しては、現時点でも0.3ms位なので、これ以上何かしても、全く寄与しないことは明らかです。が、これから8weeks、さらに巨大なインスタンスに立ち向かうときは、この計算がネックなので、出来る限りのことをやっておいても無駄にはなりません。
開発中のソルバで、INRC2 4weeksの最適値が全て求まりました。以下の通りとなりました。
n030w416-2-9-1 1670
n030w416-7-5-3 1815
n035w401-7-1-8 1360
n035w428-8-7-5 1080
n040w402-0-6-1 1565
n040w426-1-0-6 1750
n050w400-4-8-7 1315
n050w407-2-7-2 1315
n060w416-1-1-5 2450
n060w419-6-3-8 2675
n070w403-6-5-1 2380
n070w404-9-6-7 2115
n080w424-3-3-3 3300
n080w426-0-4-8 3185
n100w401-1-0-8 1170
n100w420-6-4-6 1780
n110w401-4-2-8 2330
n110w401-9-3-5 2455
n120w414-6-2-6 2020
n120w415-6-9-8 2050
未だデバッグモードで検証しながらの段階で、整数化については、なんら考慮していません。これから、本題の8Weeksについてトライ・しながら、整数化について考えていきます。
H3. Shift type successions: The shift type assignments of one nurse in two consecutive days must belong to the legal successions provided in the scenario
シフトに関するハード制約になります。
勤務連続ではなく、シフト連続になります。EはEarlyで早番、Lは、Lateで遅番、Nは、Nightで夜勤です。驚くべきは、EUでは、夜勤の連続5回というのもありえるということで、これが日本との主要な差になります。
最大パターン長6が3個もあるので、グラフは、より大きくなります。
S2. Consecutive assignments (15/30): Minimum and maximum number of consecutive assignments, per shift or global, should be respected. Their evaluation involves also the border data. Each extra or missing day is multiplied by the corresponding weight. The weights for consecutive shift constraint and for consecutive working days are respectively 15 and 30
Consecutive Assignmentsとは、連続勤務日数です。勤務=休みの否定 なので、休みラベルOを否定(✅)して最大勤務日数+1のパターンを作ってそれを禁止にします。
短いパターンならばそれほど影響はありませんが、長いパターン(一週間以上)は可能な限り避けるようにしてください。
なお、INRC2は、EUの勤務形態をモデル化していますが、この制約については、日本と同じような感じですね。