🐍

AHCのローカルテスト環境構築

2023/12/21に公開

こんにちは。
ikomaです。

先日AtCoderで行われたAHC027で念願の黄色になれました。

記念に記事を書いてみようと思い色変記事にしようか迷いましたが、それより誰かの役に立ちそうなネタを投稿したいと思います。

はじめに

みなさん、ヒューリスティックコンテスト(AHC)楽しんでますか?
正解がないからこそ、独自のアイデアが結果に素直(?)に表れるところが楽しいポイントの一つですね。
思いついたアイデアが当たってスコアが一気に良くなったときが一番楽しいです。
(思いついたアイデアを試せど試せど一向に良くならないどころか悪化する時期は苦しいです)
ですが、アルゴと比べて参加者がとても少ないのは悲しいことです。

参加者が少ない理由はたくさんありそうですが、その中の一つに環境構築が大変そうってのがありそうです。
ただ参加するだけならアルゴとそう変わらないですが、ヒューリスティックコンテストで成績を上げるためには、ローカル環境で複数の入力データを使ってしっかりテストを行い、スコアが上がったのかどうかを見極める必要があります。
これ、手作業ではやってられないので、私の環境を紹介したいと思います[1]

ローカルテスト環境

ローカルテスト実行スクリプトはこちらに公開しています。
https://gist.github.com/ikoma3/393308b2283691f32a84a3dae4a08c8b

事前準備

1. Pythonインストール

最低限、Pythonがインストールされている必要があります。
Windowsの場合はPythonから最新版をダウンロードし、インストールするとすぐに使えるようになるでしょう。

2. 公式テスタの準備

AHCでは、スコア計算を行う公式のテスタ(ビジュアライザ)が提供されることが多いです。
(無い場合は自作する必要があります)
何も考えずに落としてきましょう。

AHC027の例

Windows用のコンパイル済みバイナリを落としてきてもいいですし、「ローカル版」をダウンロードして自前ビルド[2]してもよいです。
ローカルに落としたら、zipファイルを解凍しましょう。

3. 入力ファイル準備

公式テスタを落としてくると、seed=0~49(or 99)の入力ファイルが付属されていることが多いです。
これでは少ないので、公式のジェネレータで入力ファイルをたくさん生成してください。
公式でWeb版のビジュアライザが用意されている場合は、そのページから入力ファイルを生成できる場合が多いです。こちらを使った方が楽ちんです。


AHC027のWeb版ビジュアライザから入力ファイルをダウンロードする場合はここをクリック

フォルダ構成

以下のようなフォルダ構成を想定しています。
一つのフォルダに、test.py、公式テスタ(toolsフォルダ)、解答コードを置いてください。

<プロジェクトフォルダ>
  ├── test.py
  ├── <解答コード>
  └── <tools> or <tools_x86_64-pc-windows-gnu>
         ├── in/****.txt          # テスト入力
         ├── out/****.txt         # テスト出力
         └── target/release/vis.exe   # ローカルテスタ実行ファイル 

スクリプトの修正

使用者の環境に合わせていくつかtest.pyスクリプトを修正する必要があります。

1. 問題を解くプログラムの実行コマンド設定

問題を解くプログラムがPythnの場合は、 sample.pyをあなたのソースコードのファイル名に変更してください。
Python以外の場合は、その言語を実行するコマンドに修正してください。

# プログラム実行コマンド
#  例
#   C++の場合 :a.exe
#   Rustの場合:<Rustプロジェクトフォルダ>/target/release/***.exe
PROGRAM_CMD = "python sample.py"

2. テストを行う入力ファイルのseed番号設定

どの入力ファイルでテストを実行するかを設定します。
基本的には、SIZEの値を変更すればOKです。
以下の例ではseed=0~99の100caseでテストを実行します。

START_SEED=0 # テスト対象seedの先頭番号
SIZE=100     # テスト対象seedのデータ数
STEP=1       # テスト対象seedの刻み幅

テスト対象が多すぎると時間がかかるので、場合に応じて変更するとよいでしょう。

3. 同時実行数上限設定

テストは並列実行する仕様です。
同時に並列実行する上限数を設定します。
少なすぎると時間がかかりますが、多すぎてもあまり速くなりません。
実行するPCのCPUコア数くらいを目安にするとよいでしょう[3]

# 最大並列処理数
MAX_WORKERS = 16

4. ローカルテスタのスコア出力文字列設定

テスタを実行すると、スコアを標準出力(もしくは標準エラー)に出力します。
その時、 Score = *****といった形で出力されるので、数値の前の文字列を設定してください。

# スコア表示文字列 # ローカルテスタ(ビジュアライザ)が出力する形式に合わせて変更する
TESTER_OUTPUT_SCORE_TXT = "Score ="

5. ローカルテスタの実行コマンド設定

ローカルテスタの場所と、その実行コマンドを設定してください。
AHC027の場合は以下のようになります。
vis.exeではなくtest.exeなど他の名前の場合があるので、コンテストごとに修正してください。

# ローカルテスタ テストコマンド (例:AHC027)
TESTER_DIR = "tools" # Windows用のコンパイル済みバイナリの場合は "tools_x86_64-pc-windows-gnu"
TESTER_CMD = r"target\release\vis.exe" # cargo runより直接呼んだ方が速い ※cargo build --release --bin vis で事前にビルド必要

6. 入出力ファイルフォルダ設定

入出力ファイルがあるフォルダを設定します。
TESTER_DIR基準で設定してください。
公式テスタを用いる場合は変更する必要はあまりないでしょう。

# 入出力テストファイルフォルダ
TEST_IN_DIR = "in"
TEST_OUT_DIR = "out"

テスト実行

お疲れ様です。ここまで設定できたら後は実行するだけです。
プロジェクトフォルダで以下のコマンドを実行します。

python test.py

テスト結果がリアルタイムに表示され、最後にトータル時間、1ケースの平均時間、合計スコア、対数スコア[4]の平均値が表示されます。
すべてのテストが完了したら
テスト結果が result.csvファイルに保存されます。
Gitなどのバージョン管理ソフトを用いて差分確認を行うと良いでしょう。


AHC027公式で提供されているサンプルプログラム(sample.py)を実行した結果

さいごに

いかがでしたでしょうか。
この環境を導入するだけで手軽に多数のテストができるようになったかと思います。

最初の環境構築にあまり時間を掛けず、考えることに時間を割いて楽しみましょう!

では、よいAHCライフを!

脚注
  1. Windows環境で動作確認しています。Linuxでもおそらく動きますが、確認していません。.exeなどは修正する必要があるでしょう。 ↩︎

  2. Rust言語のコンパイル環境が必要になります。 ↩︎

  3. 同時実行なしの時と比べて1実行あたりの処理速度が低下しますので、必要に応じて調整してください。 ↩︎

  4. 相対スコアを競うコンテストでは、各テストケースの絶対スコアの大きさが違いすぎて合計スコアがあまり参考にならない場合があります。そこで、対数スコアを計算しその平均値を改善の指標とするテクニックが知られています。 ↩︎

Discussion