AHCで局所探索の途中経過を可視化する

自分の備忘用。公式のビジュアライザを少しだけ変更してMP4ファイルを作成する。

1). 可視化したい状態をファイル名を連番にして出力する。

.
├── a.out
├── main.cpp
├── out
│   ├── out_0000.txt
│   ├── out_0001.txt
│   ├── out_0002.txt
│   └── out_0003.txt
└── tools

2). 公式ビジュアライザを変更する。自分の出力ファイルと同じディレクトリに、拡張子だけ変更してsvgファイルが出力されるようにする。変更するのは最後の出力の一行のみ。

fn main() {
    if std::env::args().len() != 3 {
        eprintln!("Usage: {} <input> <output>", std::env::args().nth(0).unwrap());
        return;
    }
    let in_file = std::env::args().nth(1).unwrap();
    let out_file = std::env::args().nth(2).unwrap();
    let input = std::fs::read_to_string(&in_file).unwrap_or_else(|_| { eprintln!("no such file: {}", in_file); std::process::exit(1) });
    let output = std::fs::read_to_string(&out_file).unwrap_or_else(|_| { eprintln!("no such file: {}", out_file); std::process::exit(1) });
    let input = parse_input(&input);
    let output = parse_output(&input, &output);
    let (score, svg, err) = vis_default(&input, &output);
    if err.len() > 0 {
        println!("{}", err);
    }
    println!("Score = {}", score);
    // std::fs::write("out.svg", &svg).unwrap();
    std::fs::write(format!("{}.svg", &out_file[..out_file.chars().count()-4]), &svg).unwrap();
}

3). tools/make_movie.shに以下のスクリプトを用意する

#!/bin/sh

input_file=$1
dir=$2
num=$3
for ((i = 0; i <= ${num}; i+=1))
do
    echo ${i}
    n=$(printf "%04d" $i)
    cargo run --release --bin vis ${input_file} ${dir}/out_${n}.txt
    qlmanage -t -s 512 -o ${dir}/ ${dir}/out_${n}.svg
    mv ${dir}/out_${n}.svg.png ${dir}/out_${n}.png 
done
rm ${dir}/*.svg
ffmpeg -i ${dir}/out_%04d.png -pix_fmt yuv420p -f mp4 ${dir}/output.mp4

4). スクリプトを実行する。

$ ./make_movie.sh [インプットファイル] [1).で用意したファイルがあるディレクトリ] [連番の終わりの数]

AHC005で作成したもの