最近、整数計画ソルバーの
scip
をいじっている。
「一次の不等式(あるいは等式)の問題に落とし込」んでやればscipがサクっと解いてくれる。
ネット内の情報を参考に
数独、お絵かき19(いわいオリジナル)、シャカシャカ(ニコリ)
を解くプログラムをscipとC#を使ってできた。
その記事はまた。
##################
今回の問題は
「5枚あるカードのうちAが2枚か4枚だ」
というのをどう不等式だけで書くか
ということで
1枚目のカードがAか否か a1 (0 か 1)
Aの総数はsumは
a1 + a2 + a3 + a4 + a5 = sum
「Aが2枚だ」は
sum == 2
と等式で書けばよい。
だが、
「Aが2枚か4枚か」は
sum===2 or sum===4 と書ければいいけれど、
その方法は用意されてないようなので。
(このあたり、いわいの調査不足の可能性あり)
不等式で書ききりたいわけで。
フラグを用意して
flag2 このフラグが1のときはAは2枚だ
フラグが0ときは何枚でもよい
flag4 このフラグが1のときはAは4枚だ
フラグが0のときは何枚でもよい
があれば、
flag2+flag4 >= 1
で記述できる。
(flag2とflag4は同時に成り立つことはない)
あとは、flag2、flag4とsumの関係を書いてやるとよくて、
例えば、(書き方はいろいろある)
sum => 2 * flag2
sum =< -3 *flag2 +5
flag4とsumの関係は
sum => 4 * flag4
sum =< -1 * flag4 +5
でよいので。
まとめると
a1 + a2 + a3 + a4 + a5 = sum
sum => 2 * flag2
sum =< -3 * flag2 +5
sum => 4 * flag4
sum =< -1 * flag4 +5
になる。
で、いいかなぁ~。
式自体はあっていると思う。
scipで動かした感じOKだった。
だが、
もっと式自体が整理できるかも。
だし、
scipやその周辺に他の記述方法、解決方法がある可能性はある。
し。
以上
「scip」で剰余計算(「%」)ができるなら、 > 0
sum % 2
で偶奇判定して、0を除外すればよいので
sum == 2 or sum == 4
は
((1 + sum) % 2) * sum
と書けます。