noise

計算機科学や各種設定のメモ

雑感

気になった本

直線数最適化障害物回避問題

f:id:with137d:20151216230500p:plain

解きたい問題

  • 障害物のある平面において起点と終点を結ぶ経路を探索し直線数を最小化したい。
  • 障害物は線分で与えられる。
  • 経路の長さは目的としない。

f:id:with137d:20151216230507p:plain この画像は問題の単なる一例であり、障害物は平面上に自由に置けるものとする。

解決手順

  • 適当な細かさのGridに対応させて考える。
  • 障害物により格子点の連結を切断する。
  • BeamSearchを用いて起点から終点までの経路を求める。
  • 得られた点列をGreedyに直線列に変換。
  • 焼きなまし法(SimulatedAnealing)で直線数を減らす。

Rubyによるソースコード(Ideone)

考察

  • 与える問題のパラメータによってGridの細かさなどを変更する必要がある。
  • BeamSearchは驚くほど便利。
  • SimulatedAnealingは「近傍をどう生成するのか」が難しい。
    • 今回は、「経路のうちの一点を選ぶ」「移動先としてランダムに新しい格子点を選択」「障害物に当たらないかを検査」「当たらないなら前後の直線を縮約できればやる」として近傍を生成した。
  • はじめGridなどを考えずにデカルト平面上でSA法を適用し経路探索と直線数最小化を一度にしようとしたが精度や計算量的に失敗だった。
  • 残る問題としては交差判定に時間がかかっている点。SA法の中で近傍探索する際にすべての障害物と着目する直線との交差判定をしている。BoundingBoxなどで不必要な交差判定をなくしたほうが良い。

    結果

    f:id:with137d:20151216230514p:plain

可視化について

  • D3.jsを用いて描画した。
  • ソルバはJSON形式で結果を出力。
  • ruby -run httpd -- . -p 8000によりHTTPサーバを立てる。
  • カレントディレクトリにJSONファイルとそれを表示するHTMLファイルを置く。
  • SVGPNGに変換し保存。変換用コードは下に示すJavaScriptコード。

結果表示用HTML(codepad)

  • WindowsからLinuxPuttyで接続して開発しているためブラウザでデータをやり取りしたかった。WinSCPは手間。D3.jsによる可視化はその点においても親和性の高いやり方だと思った。
  • SVGからPNG画像の変換についてはSave SVG as an Image | TechSlidesを参考にした。

VimのViewを自動的に保存/復帰

autocmd BufWinLeave ?* if &buftype == '' | mkview | endif
autocmd BufWinEnter ?* if &buftype == '' | silent loadview | endif
  • buftypeを見ることで特殊なバッファ(helpなど)を処理から除外
  • ファイルパターンに ?* を指定することでファイル名を指定しない呼び出し(vimコマンドを無引数で実行するときなど)を除外

大域最小カット(Global Minimum Cut)

問題

連結無向グラフG=(V,E)のカットのうち最小のものを求める。

実装

ソースコード(IdeOne)

解説

  • 乱択アルゴリズムによる実装。
  • 一辺をランダムに選んで縮約していく。
  • 最後に2点残る。これらの点に縮約された点が大域最小カットである可能性は1/\binom{n}{2}以上。
  • 頂点の数をnとし、\binom {n}{2} \ln nアルゴリズムを繰り返すとき、大域最小カットが得られない確率は\frac{1}{n}以下となる。
  • 決定的アルゴリズムの素朴な実装は始点sを任意に選び、s-tカットアルゴリズムn-1回使用して最小値をとったものとなる。これは多項式時間アルゴリズムである。
  • このKargerによる方法をさらに改良したアルゴリズムがある。参照(pdf)
  • 大域最小カット問題は画像の領域分割に使えるらしい。

最近点対問題(Closest Pair of Points)

問題の定義

平面上のn個の点の中からユークリッド距離が最小の点の組み合わせを出力する。

実装

ソースコード(Ideone)

解説

  • 入力をランダムにシャッフルしたのちに逐次添加アルゴリズムを用いる。
  • アルゴリズムが実行される任意の時点において、一辺の長さ\frac{\delta}{2}のメッシュ構造が保たれている。\deltaはその時点で発見済みの二点間の最小距離。
  • このメッシュ構造においては、最小距離を更新される可能性のある点は、着目している点の周り25個の小正方形内に限られる。
  • 計算量はO(n)。素朴な実装ではO(n^{2})、ソートして分割統治するアルゴリズムではO(n \log n)であるから驚くべき改善である。

PSReadline

PowerShellの初期状態ではBashのように

  • Ctrl+P/Ctrl+Nキーでコマンド履歴を呼び出し
  • PageUp/PageDownでバッファを移動

などを行うことができない。
この問題はPSReadLineモジュールによって解決する。
これでかなり使いやすくなった。

インストール

(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
Import-Module PsGet
Install-Module PsReadline

ちなみにWindows10からはPsGetを導入する必要はないらしい。標準でインストールされるPowerShell5に新しいパッケージマネージャが組み込まれているそうだ。

Install-Module -Name PSReadline

とするだけでインストールできるみたいだ。

設定

if ($host.Name -eq 'ConsoleHost')
{
     Import-Module PSReadline
     Set-PSReadlineOption -EditMode Emacs -BellStyle None
}

プロファイルに上記コードを追加する。

VLCプレイヤーでの文字化け問題

VLC Playerを使用時にプレイリスト内のタイトル等の曲情報が文字化けする問題があった。
はじめにフォントの設定の問題かと思ったがそうではなかった。
ID3タグ内の情報がShiftJISで保存されていることが原因だった。
とりあえずMP3内のID3v2タグをUnicodeに変換するID3Uniというソフトで変換して対処した。