の末尾に書いた通り、ortoolsを使おうとしている。 そのためには定式化が必要で、今見ている問題がどのタイプの問題かを判断する必要がある。
ここら辺で重大なことに気づいた。巡回サラリーマン問題などは点と点の間に距離があり、それが問題だった。しかし、今回の塗装の問題は塗る色の間に距離などない。白と黄色の距離と、白とくろの距離は同じである(なぜならエアブラシのカップの中に入れる色が何であれ、手間は変わらないからである)。
この問題、もしかしてNP困難ではないのでは?
問題を整理する
~ のN個の色を塗るとする。 また、 のような塗装順の制約がP個ある。 このとき、最小となるような塗装順を見つけたい。
これは、書き換えると次のような問題になる。
~ のN個の記号がある。 ~ をそれぞれ1つ以上含んだ最短の記号列を求めよ。 ただし、より後に必ずを含む必要がある、といった制約LがP個ある。
こう考えるとNP困難ではない気がする。
多角的にこの問題を考えよう。 まず、[text: L_1] ~ [text: L_P]のどれにも含まれていない記号は考慮からすべて外せる。というのは、制約に含まれる記号を制約を満たすように順序付けしたあとは、制約に含まれていない記号はその列の任意の間に好きな順序でおけるからである。先頭にあまり全てをおいても良いし、末尾でも良い。ランダムでも数字順にソートでもいが、そのどれでも塗装回数に影響しない。
となると問題は以下のように書き換えられる。
~ のN個の記号がある。 ~ をそれぞれ1つ以上含んだ最短の記号列を求めよ。 ただし、より後に必ずを含む必要がある、といった制約LがP個ある。また、~ は制約~ の中に必ず1度以上出てくる。
これを図として表現すると、NxNの行列(対角線はn/a)になる。 例えば - のあとで - のあとで - のあとで
というルールは次の行列で表現できる。
先に通る点 \ 後に通る点 | |||
---|---|---|---|
n/a | true | true | |
true | n/a | false | |
false | false | n/a |
この行列を持って最適化する。それが、この問題の解き方(の気がする・・・)。
もしかして、DPで行ける?
2022/08/11追記
重みがないから更に効率的なアルゴリズムがありそうと2,3日調査しながら頭をひねった結果、制約を一つずつ見ながらtreeを作っていくロジックを考えついた。