From 114ad016616135c4ceb70ea6fc0d6c284665fdcd Mon Sep 17 00:00:00 2001 From: yaneurao Date: Wed, 27 Nov 2024 22:04:17 +0900 Subject: [PATCH] =?UTF-8?q?-=20meanSquaredScore=E5=B0=8E=E5=85=A5=E3=80=82?= =?UTF-8?q?=20-=20Value=E3=82=92enum=E3=81=8B=E3=82=89int=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=80=82=20-=20Value=E9=96=A2=E9=80=A3?= =?UTF-8?q?=E3=81=AEoperator=E5=AE=9A=E7=BE=A9=E3=82=92=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engine/yaneuraou-engine/yaneuraou-param.h | 4 +- .../yaneuraou-engine/yaneuraou-search.cpp | 33 +++++---- source/extra/macros.h | 12 ---- source/search.h | 3 + source/types.h | 70 ++++++++++--------- 5 files changed, 64 insertions(+), 58 deletions(-) diff --git a/source/engine/yaneuraou-engine/yaneuraou-param.h b/source/engine/yaneuraou-engine/yaneuraou-param.h index 0638fe6ca..81e74ed78 100644 --- a/source/engine/yaneuraou-engine/yaneuraou-param.h +++ b/source/engine/yaneuraou-engine/yaneuraou-param.h @@ -250,9 +250,9 @@ PARAM_DEFINE PARAM_ASPIRATION_SEARCH1 = 10; // aspiration searchの定数。 // 重要度 ★★☆☆☆ -// 元の値 = Stockfish 16 : 15335, Stockfish 17 : 13797 , step = 1000 +// 元の値 = Stockfish 16 : 15335, Stockfish 17 : 13797,13461 , step = 1000 // [PARAM] min:10000,max:20000,step:1,interval:1,time_rate:1,fixed -PARAM_DEFINE PARAM_ASPIRATION_SEARCH2 = 13797; +PARAM_DEFINE PARAM_ASPIRATION_SEARCH2 = 13461; // MovePicker diff --git a/source/engine/yaneuraou-engine/yaneuraou-search.cpp b/source/engine/yaneuraou-engine/yaneuraou-search.cpp index 87d03b9e0..4909804f2 100644 --- a/source/engine/yaneuraou-engine/yaneuraou-search.cpp +++ b/source/engine/yaneuraou-engine/yaneuraou-search.cpp @@ -1096,8 +1096,8 @@ void Thread::search() // Stockfish 16では10に変更された。 // Stockfish 17では 5に変更された。 + delta = Value(PARAM_ASPIRATION_SEARCH1) + std::abs(rootMoves[pvIdx].meanSquaredScore) / PARAM_ASPIRATION_SEARCH2; Value avg = rootMoves[pvIdx].averageScore; - delta = Value(PARAM_ASPIRATION_SEARCH1) + int(avg) * avg / PARAM_ASPIRATION_SEARCH2; alpha = std::max(avg - delta,-VALUE_INFINITE); beta = std::min(avg + delta, VALUE_INFINITE); @@ -1782,7 +1782,8 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo && ttData.depth > depth - (ttData.value <= beta) // 置換表に登録されている探索深さのほうが深くて && ttData.value != VALUE_NONE // Can happen when !ttHit or when access race in probe() // !ttHitの場合やprobe()でのアクセス競合時に発生する可能性があります。 - && (ttData.bound & (ttData.value >= beta ? BOUND_LOWER : BOUND_UPPER))) + && (ttData.bound & (ttData.value >= beta ? BOUND_LOWER : BOUND_UPPER)) + && (cutNode == (ttData.value >= beta) || depth > 8)) // ■ 解説 // // ttValueが下界(真の評価値はこれより大きい)もしくはジャストな値で、かつttValue >= beta超えならbeta cutされる @@ -3122,8 +3123,17 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo RootMove& rm = *std::find(thisThread->rootMoves.begin(), thisThread->rootMoves.end() , move); + // TODO : あとで + //rm.effort += nodes - nodeCount; + // rootの平均スコアを求める。aspiration searchで用いる。 - rm.averageScore = rm.averageScore != -VALUE_INFINITE ? (value + rm.averageScore) / 2 : value; + rm.averageScore = + rm.averageScore != -VALUE_INFINITE ? (value + rm.averageScore) / 2 : value; + + // 二乗平均スコア。aspiration searchで用いる。 + rm.meanSquaredScore = rm.meanSquaredScore != -VALUE_INFINITE * VALUE_INFINITE + ? (value * std::abs(value) + rm.meanSquaredScore) / 2 + : value * std::abs(value); // PV move or new best move? // PVの指し手か、新しいbest moveか? @@ -3421,23 +3431,22 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo // correction historyは実装しない。 #if 0 // Adjust correction history - if (!ss->inCheck && (!bestMove || !pos.capture(bestMove)) - && !(bestValue >= beta && bestValue <= ss->staticEval) - && !(!bestMove && bestValue >= ss->staticEval)) + if (!ss->inCheck && !(bestMove && pos.capture(bestMove)) + && ((bestValue < ss->staticEval && bestValue < beta) // negative correction & no fail high + || (bestValue > ss->staticEval && bestMove))) // positive correction & no fail low { const auto m = (ss - 1)->currentMove; auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8, -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4); thisThread->pawnCorrectionHistory[us][pawn_structure_index(pos)] - << bonus * 101 / 128; - thisThread->materialCorrectionHistory[us][material_index(pos)] << bonus * 99 / 128; - thisThread->majorPieceCorrectionHistory[us][major_piece_index(pos)] << bonus * 157 / 128; - thisThread->minorPieceCorrectionHistory[us][minor_piece_index(pos)] << bonus * 153 / 128; + << bonus * 107 / 128; + thisThread->majorPieceCorrectionHistory[us][major_piece_index(pos)] << bonus * 162 / 128; + thisThread->minorPieceCorrectionHistory[us][minor_piece_index(pos)] << bonus * 148 / 128; thisThread->nonPawnCorrectionHistory[WHITE][us][non_pawn_index(pos)] - << bonus * 123 / 128; + << bonus * 122 / 128; thisThread->nonPawnCorrectionHistory[BLACK][us][non_pawn_index(pos)] - << bonus * 165 / 128; + << bonus * 185 / 128; if (m.is_ok()) (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] << bonus; diff --git a/source/extra/macros.h b/source/extra/macros.h index 6db399410..1d2be49c6 100644 --- a/source/extra/macros.h +++ b/source/extra/macros.h @@ -47,22 +47,10 @@ ENABLE_FULL_OPERATORS_ON(Piece) ENABLE_INCR_OPERATORS_ON(PieceType) ENABLE_BASE_OPERATORS_ON(PieceType) ENABLE_FULL_OPERATORS_ON(PieceNumber) -ENABLE_FULL_OPERATORS_ON(Value) ENABLE_FULL_OPERATORS_ON(Hand) ENABLE_FULL_OPERATORS_ON(Eval::BonaPiece) ENABLE_FULL_OPERATORS_ON(Effect8::Direct) -// enumに対してint型との加算と減算を提供するマクロ。Value型など一部の型はこれがないと不便。(やねうら王独自拡張) - -#define ENABLE_ADD_SUB_OPERATORS_ON(T) \ -constexpr T operator+(T v, int i) { return T(int(v) + i); } \ -constexpr T operator-(T v, int i) { return T(int(v) - i); } \ -inline T& operator+=(T& v, int i) { return v = v + i; } \ -inline T& operator-=(T& v, int i) { return v = v - i; } - -ENABLE_ADD_SUB_OPERATORS_ON(Value) - - // enumに対して標準的なビット演算を定義するマクロ(やねうら王独自拡張) #define ENABLE_BIT_OPERATORS_ON(T) \ inline T operator&(const T d1, const T d2) { return T(int(d1) & int(d2)); } \ diff --git a/source/search.h b/source/search.h index 4aa439b00..ee115ef42 100644 --- a/source/search.h +++ b/source/search.h @@ -104,6 +104,9 @@ struct RootMove // aspiration searchの時に用いる。previousScoreの移動平均。 Value averageScore = -VALUE_INFINITE; + // aspiration searchの時に用いる。二乗平均スコア。 + Value meanSquaredScore = - VALUE_INFINITE * VALUE_INFINITE; + // USIに出力する用のscore Value usiScore = -VALUE_INFINITE; diff --git a/source/types.h b/source/types.h index d2e336d88..57a7ec351 100644 --- a/source/types.h +++ b/source/types.h @@ -433,47 +433,53 @@ enum Bound { // Stockfishでは、 VALUE_TB_LOSS_IN_MAX_PLY // やねうら王でも同様。 // -enum Value : int32_t -{ - VALUE_ZERO = 0, +// Value is used as an alias for int, this is done to differentiate between a search +// value and any other integer value. The values used in search are always supposed +// to be in the range (-VALUE_NONE, VALUE_NONE] and should not exceed this range. - // 引き分け時のスコア(千日手のスコアリングなどで用いる) - VALUE_DRAW = 0, +// Valueはint型のエイリアスとして使用されています。これは、検索に使用される値と +// その他の整数値を区別するために行われています。検索で使用される値は +// 常に(-VALUE_NONE, VALUE_NONE]の範囲内である必要があり、この範囲を超えてはなりません。 - // 無効な値 - VALUE_NONE = 32002, +using Value = int; - // Valueの取りうる最大値(最小値はこの符号を反転させた値) - VALUE_INFINITE = 32001, +constexpr Value VALUE_ZERO = 0; +// 引き分け時のスコア(千日手のスコアリングなどで用いる) +constexpr Value VALUE_DRAW = 0; - // 0手詰めのスコア(rootで詰んでいるときのscore) - // 例えば、3手詰めならこの値より3少ない。 - VALUE_MATE = 32000, +// 無効な値 +constexpr Value VALUE_NONE = 32002; - VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY , // MAX_PLYでの詰みのときのスコア。 - VALUE_MATED_IN_MAX_PLY = -VALUE_MATE_IN_MAX_PLY , // MAX_PLYで詰まされるときのスコア。 +// Valueの取りうる最大値(最小値はこの符号を反転させた値) +constexpr Value VALUE_INFINITE = 32001; - // チェスの終盤DB(tablebase)によって得られた詰みを表現するスコアらしいが、 - // Stockfishとの互換性のためにこのシンボルはStockfishと同様に定義しておく。 - VALUE_TB = VALUE_MATE_IN_MAX_PLY - 1, - VALUE_TB_WIN_IN_MAX_PLY = VALUE_MATE - MAX_PLY, - VALUE_TB_LOSS_IN_MAX_PLY = -VALUE_TB_WIN_IN_MAX_PLY, +// 0手詰めのスコア(rootで詰んでいるときのscore) +// 例えば、3手詰めならこの値より3少ない。 +constexpr Value VALUE_MATE = 32000; - // 千日手による優等局面への突入したときのスコア - // ※ これを詰みのスコアの仲間としてしまうと、詰みのスコアをrootからの手数で - // 計算しなおすときにおかしくなる。これは評価値の仲間として扱うことにする。 - // よって、これは、VALUE_MAX_EVALと同じ値にしておく。 - VALUE_SUPERIOR = VALUE_TB_WIN_IN_MAX_PLY - 1, +constexpr Value VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY; // MAX_PLYでの詰みのときのスコア。 +constexpr Value VALUE_MATED_IN_MAX_PLY = -VALUE_MATE_IN_MAX_PLY; // MAX_PLYで詰まされるときのスコア。 - // 評価関数の返す値の最大値、最小値 - VALUE_MAX_EVAL = VALUE_SUPERIOR, - VALUE_MIN_EVAL = -VALUE_MAX_EVAL, +// チェスの終盤DB(tablebase)によって得られた詰みを表現するスコアらしいが、 +// Stockfishとの互換性のためにこのシンボルはStockfishと同様に定義しておく。 +constexpr Value VALUE_TB = VALUE_MATE_IN_MAX_PLY - 1; +constexpr Value VALUE_TB_WIN_IN_MAX_PLY = VALUE_MATE - MAX_PLY; +constexpr Value VALUE_TB_LOSS_IN_MAX_PLY = -VALUE_TB_WIN_IN_MAX_PLY; - // 評価関数がまだ呼び出されていないということを示すのに使う特殊な定数 - // StateInfo::sum.p[0][0]にこの値を格納して、マーカーとするのだが、このsumのp[0][0]は、ΣBKPPの計算結果であり、 - // 16bitの範囲で収まるとは限らないため、もっと大きな数にしておく必要がある。 - VALUE_NOT_EVALUATED = INT32_MAX, -}; +// 千日手による優等局面への突入したときのスコア +// ※ これを詰みのスコアの仲間としてしまうと、詰みのスコアをrootからの手数で +// 計算しなおすときにおかしくなる。これは評価値の仲間として扱うことにする。 +// よって、これは、VALUE_MAX_EVALと同じ値にしておく。 +constexpr Value VALUE_SUPERIOR = VALUE_TB_WIN_IN_MAX_PLY - 1; + +// 評価関数の返す値の最大値、最小値 +constexpr Value VALUE_MAX_EVAL = VALUE_SUPERIOR; +constexpr Value VALUE_MIN_EVAL = -VALUE_MAX_EVAL; + +// 評価関数がまだ呼び出されていないということを示すのに使う特殊な定数 +// StateInfo::sum.p[0][0]にこの値を格納して、マーカーとするのだが、このsumのp[0][0]は、ΣBKPPの計算結果であり、 +// 16bitの範囲で収まるとは限らないため、もっと大きな数にしておく必要がある。 +constexpr Value VALUE_NOT_EVALUATED = INT32_MAX; // ply手で詰ませるときのスコア constexpr Value mate_in(int ply) { return (Value)(VALUE_MATE - ply); }