最小費用ソート(ALDS1_6_D)の解法の正当性(メモ)
Minimum Cost Sort (最小費用ソート)という問題がある.
最小コストソート | アルゴリズムとデータ構造 | Aizu Online Judge
この問題を解くことができず,また正解コードをみてもその正当性がよくわからなかった. まじめに考えたら正当性の証明ができつつあるので,備忘のため記事にしておく. 頭が整理されていないところもあり, 細かい部分はしっかり書いていなかったり,記法が適当だったりという箇所もあります. 指摘・質問などを歓迎します.
なお,偉い人達がかいた正解コードは上記ページで🔍アイコンをクリックすると見ることができる. また AOJ の問題(の一部?)は
プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
- 作者: 渡部有隆,Ozy(協力),秋葉拓哉(協力)
- 出版社/メーカー: マイナビ
- 発売日: 2015/01/30
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (4件) を見る
問題設定
最小費用ソート問題の設定は以下の通りである.オリジナルの問題と本質的には同じだが,説明を簡単にするために等価な別表現で書いている.
入力
:問題サイズ
:非負な増加列
:置換( は 次の対象群)
出力
互換 の重みを と定義する. 置換 を互換の積 に分解するとき, 分解の重みを と定義する. の互換の積での分解のうち,もっとも重みの小さいものの重みを求めよ.
解法
具体的な分解を与えるアルゴリズムを紹介する. 正当性の証明は次節で与える.
置換 の軌道分解(1次以上の巡回置換での分解) とその表現を考える. この分解では,任意の ] が必ずいずれかの巡回置換の表現に登場する.
分解を適当に並べ替えて, が に関するものであるようにしておく. また,ここで登場する各巡回置換 は, が登場する要素のうち 最軽量のものであるものを選ぶ.つまり, であるように巡回置換の表現を固定する. したがって特に である.
巡回置換 を のみを用いた互換の積に分解する場合, 最小重みの分解は である. (∵ このような分解の重みの式に が必ず1回は登場する. またこのような分解の長さが以上であり,重みの式は要素を 個以上含む足し算になる. したがって,最も軽く見積もっても分解の重みは であり, これは の重みと一致する.)
上記の分解を用いて(限られた操作のなかでの)巡回置換 の重み を定義する. 軌道分解における異なる2つの巡回置換 の重みの和は
であり,したがってこの重みの互換による分解☆をもつ.一方, は巡回置換となるが,その重みは である.したがって, は重み
の互換による分解★をもつ. 分解☆と★の重みの差は である. したがって,これが正の場合分解は分解 ★ を採用すべきであり,そうでない場合は分解 ☆ を採用すべきである.この量を とする.
このような観察から,最適な分解を与えるアルゴリズムは次のものであると予測する.
単一のサイクル の重み の 分解に対して,左から をかけた分解を計算する.
これは頂点の数について線形時間で計算できる. とくに,最小の重みだけを計算したい場合は 「全てのサイクルについてとサイクルの重みを計算する」だけで十分である.
正当性証明
この問題は計算量を度外視すれば最短路問題である.すなわち,最小費用ソートは を頂点集合とし,互換でつながる頂点同士に互換の重みで重み付けした枝を張ったグラフ上での, から への最短路を求める問題である.したがって,部分路が再び最短路になっている,という性質が証明に使えそうである.
主張1
の互換による分解のうち, という形であり の軌道の数が の軌道の数より 1 小さく, の軌道の数が の 軌道の数より 1 大きいもののみを考える.この性質 ◆ を満たす互換による分解のうち最適な 分解は,アルゴリズムで求められるものである.
∵ 軌道の数を減らす互換を左からかけていくことは,軌道を統合していくことにほかならない. 2つの軌道を統合する場合,各々の最小の要素同士を交換して統合するのが最適である. これは,軌道の統合を木(全体では森)で表現したときの,ルートからの帰納法から従う.
また,軌道の統合においては を含むサイクルと他のサイクルを統合していくのが最適である. (そうでないものを考えた場合,よりよい統合方法が構成できる.)(したがって,軌道の統合を 表現する森は最適に統合する場合は木になり,特にくし形( を含むサイクルと他のサイクルを統合するもの)になる)
くし形のうち,最適な統合の方法(の互換の積による表現)はアルゴリズムにあるよう であることは簡単に確認できる.
主張2
の互換による分解のうち最適な分解は,上記アルゴリズムで求められるものである.
∵ 最適な互換による分解が主張1にある分解 が存在することを示せば十分である. そのためには,主張1の形でない最適な分解から矛盾を導くか,あるいは同じ重みの主張1の形の分解を構成すれば十分である.最適な分解を と表す.ただし:
- :適当な互換.
- の軌道の数が の軌道の数より 1 大きい
- の軌道の数が の軌道の数より 1 小さい
- の軌道の数が の軌道の数より 1 大きい
(分解の最後の互換は,軌道の数を増やすようなものでなければならないので,かならずこのように表すことができる.)ここでは特に が最大であるようなものを採用する.
このとき, は の最適な分解であり, また は の最適な分解である. の軌道は,もともと で軌道であったものと,新しく出来た軌道(ちょうど2つ)に分類できる.新しい軌道が によって他と統合されないのであれば, という分解が存在し, であれば の最大性に矛盾し, であれば主張1の形式の最適な互換を構成できる.したがって
- 新しく出来た軌道が を含む
- 新しく出来た軌道が を含まない
の2通りの状況を考えればOKだが, の後はくし形の統合と軌道ごとの分解が待っていることから, いずれの場合においても が の最適な分解でないことがわかり,仮定と矛盾.
ひとこと
途中で面倒になって適当な記事になってしまった.本人の備忘のための記事だけれど,人の役に少しでも立てば幸いです. 細かい部分は省略しているが,お絵かきをすると分かりやすい.(お絵かきをしてブログに貼るのはサボった.)
この問題を見てプログラミングコンテストの時間枠で(おおざっぱな証明付きで)正解にたどり着けるひとはそうそう居ないように思うのだけど,強い人はできちゃうんだろうか.