ビームサーチ用テンプレート
単純なビームサーチ
- 実装
- Stateクラス
- 状態を定義
- 評価関数を定義
- ハッシュ関数を定義
- デバッグ用printを実装
- generate_next_states()関数
- 重複排除
- 改善
- 行動の改善
- 評価関数の改善
- 出力を永続stackにする
- 状態のコピーコスト削減(状態のサイズを小さくする、スコアだけを先に計算して上位のみ状態を生成する)
- priority_queue部分の改善(逆にしてBEAM_WIDTH個以上ならpopする、など)
- 重複排除
- 多様性確保
- 評価値、ハッシュ値の差分計算
- ビーム幅の調整、自動調整
- 差分更新可能な場合は、オイラーツアービームサーチなどに変更
- など
struct BeamConfig {
int MAX_TURN;
int BEAM_WIDTH;
};
struct State {
// ...
double eval; // 評価値
uint64_t hash; // ハッシュ値
vector<int> actions; // 行動列
State() : eval(compute_eval()), hash(compute_hash()) {
}
// 現在の状態から愚直に評価値を計算
double compute_eval() {
// ...
return 0;
}
// 現在の状態から愚直にハッシュ値を計算
uint64_t compute_hash() {
// ...
return 0;
}
void print() {
// ...
}
inline bool operator<(const State& other) const {
return eval < other.eval;
}
inline bool operator>(const State& other) const {
return eval > other.eval;
}
};
using Heap = priority_queue<State>; // 最大化タスク
// using Heap = priority_queue<State, vector<State>, greater<State>>; // 最小化タスク
void generate_next_states(Heap& next_states, const State& state) {
State next_state = state;
// ...
next_state.eval = 0;
next_state.hash = 0;
next_state.actions.push_back(0);
next_states.push(next_state);
}
void solve_beam(const BeamConfig& config) {
State init_state;
Heap states;
states.push(init_state);
rep(t, config.MAX_TURN) {
Heap next_states;
rep(b, config.BEAM_WIDTH) {
if (states.empty()) break;
generate_next_states(next_states, states.top());
states.pop();
}
swap(states, next_states);
}
assert(!states.empty());
State best_state = states.top();
// ...
}