Skip to content

Commit

Permalink
Merge pull request #352 from jhellis3/time_update_111
Browse files Browse the repository at this point in the history
Time Update
  • Loading branch information
glinscott authored Apr 18, 2018
2 parents f4f82e5 + 159b74b commit 30a8416
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 61 deletions.
84 changes: 27 additions & 57 deletions src/TimeMan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,48 +25,30 @@

TimeManagement Time; // Our global time management object

namespace {
// move_importance() is a skew-logistic function based on naive statistical
// analysis of "how many games are still undecided after n half-moves". Game
// is considered "undecided" as long as neither side has >275cp advantage.
// Data was extracted from the CCRL game database with some simple filtering criteria.

enum TimeType { OptimumTime, MaxTime };
double move_importance(int ply) {

const int MoveHorizon = 50; // Plan time management at most this many moves ahead
const double MaxRatio = 7.3; // When in trouble, we can step over reserved time with this ratio
const double StealRatio = 0.34; // However we must not steal time from remaining moves over this ratio
const double XScale = 6.85;
const double XShift = 64.5;
const double Skew = 0.171;

return pow((1 + exp((ply - XShift) / XScale)), -Skew) + DBL_MIN; // Ensure non-zero
}

// move_importance() is a skew-logistic function based on naive statistical
// analysis of "how many games are still undecided after n half-moves". Game
// is considered "undecided" as long as neither side has >275cp advantage.
// Data was extracted from the CCRL game database with some simple filtering criteria.
int remaining(int myTime, int movesToGo, int ply) {

double move_importance(int ply) {
double moveImportance = move_importance(ply) * cfg_slowmover / 100; // Slow Mover Ratio
double otherMovesImportance = 0;

const double XScale = 6.85;
const double XShift = 64.5;
const double Skew = 0.171;
for (int i = 1; i < movesToGo; ++i)
otherMovesImportance += move_importance(ply + 2 * i);

return pow((1 + exp((ply - XShift) / XScale)), -Skew) + DBL_MIN; // Ensure non-zero
}

template<TimeType T>
int remaining(int myTime, int movesToGo, int ply, int slowMover) {

const double TMaxRatio = (T == OptimumTime ? 1 : MaxRatio);
const double TStealRatio = (T == OptimumTime ? 0 : StealRatio);

double moveImportance = (move_importance(ply) * slowMover) / 100;
double otherMovesImportance = 0;

for (int i = 1; i < movesToGo; ++i)
otherMovesImportance += move_importance(ply + 2 * i);

double ratio1 = (TMaxRatio * moveImportance) / (TMaxRatio * moveImportance + otherMovesImportance);
double ratio2 = (moveImportance + TStealRatio * otherMovesImportance) / (moveImportance + otherMovesImportance);

return int(myTime * std::min(ratio1, ratio2)); // Intel C++ asks for an explicit cast
}

} // namespace
return int(myTime * moveImportance / (moveImportance + otherMovesImportance)); // Intel C++ asks for an explicit cast
}


/// init() is called at the beginning of the search and calculates the allowed
Expand All @@ -80,28 +62,16 @@ namespace {

void TimeManagement::init(Color us, int ply) {

int minThinkingTime = std::min(20, Limits.time[us] / 5);
int moveOverhead = 30;
int MoveHorizon = Limits.movestogo ? std::min(Limits.movestogo - 1, 50) : 50;

startTime = Limits.startTime;
optimumTime = maximumTime = Limits.time[us];

const int MaxMTG = Limits.movestogo ? std::min(Limits.movestogo, MoveHorizon) : MoveHorizon;

// We calculate optimum time usage for different hypothetical "moves to go"-values
// and choose the minimum of calculated search time values. Usually the greatest
// hypMTG gives the minimum values.
for (int hypMTG = 1; hypMTG <= MaxMTG; ++hypMTG)
{
// Calculate thinking time for hypothetical "moves to go"-value
int hypMyTime = Limits.time[us]
+ Limits.inc[us] * (hypMTG - 1)
- 30 * (2 + std::min(hypMTG, 40));

hypMyTime = std::max(hypMyTime, 0);
startTime = Limits.startTime;
optimumTime = maximumTime = std::max(Limits.time[us] - 3 * moveOverhead, minThinkingTime);

int t1 = remaining<OptimumTime>(hypMyTime, hypMTG, ply, cfg_slowmover);
int t2 = remaining<MaxTime >(hypMyTime, hypMTG, ply, cfg_slowmover);
// Calculate thinking time for hypothetical "moves to go"-value
int hypMyTime = std::max (0, Limits.time[us] + (Limits.inc[us] - moveOverhead) * MoveHorizon);

optimumTime = std::min(t1, optimumTime);
maximumTime = std::min(t2, maximumTime);
}
}
optimumTime = std::min(minThinkingTime + remaining(hypMyTime, MoveHorizon, ply), optimumTime);
maximumTime = std::min(optimumTime * 7, maximumTime);
}
9 changes: 5 additions & 4 deletions src/UCTSearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ Move UCTSearch::get_best_move() {

// Check whether to randomize the best move proportional
// to the (exponentiated) visit counts.

if (cfg_randomize) {
auto root_temperature = 1.0f;
// If a temperature decay schedule is set, calculate root temperature from
// ply count and decay constant. Set default value for too small root temperature.
// ply count and decay constant. Set default value for too small root temperature.
if (cfg_root_temp_decay > 0) {
root_temperature = get_root_temperature();
myprintf("Game ply: %d, root temperature: %5.2f \n",bh_.cur().game_ply()+1, root_temperature);
}
}
m_root->randomize_first_proportionally(root_temperature);
}

Expand Down Expand Up @@ -386,6 +386,7 @@ Move UCTSearch::think(BoardHistory&& new_bh) {

Time.init(bh_.cur().side_to_move(), bh_.cur().game_ply());
m_target_time = get_search_time();
m_max_time = Time.maximum();
m_start_time = Limits.timeStarted();

// create a sorted list of legal moves (make sure we
Expand Down Expand Up @@ -502,7 +503,7 @@ bool UCTSearch::should_halt_search() {
if (Limits.infinite) return false;
auto elapsed_millis = now() - m_start_time;
return m_target_time < 0 ? pv_limit_reached()
: m_target_time < elapsed_millis;
: (m_target_time < elapsed_millis || elapsed_millis > m_max_time);
}

// Asks the search to stop politely
Expand Down
1 change: 1 addition & 0 deletions src/UCTSearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class UCTSearch {
std::atomic<int> m_nodes{0};
std::atomic<int> m_playouts{0};
int64_t m_target_time{0};
int64_t m_max_time{0};
int64_t m_start_time{0};
std::atomic<bool> m_run{false};
int m_maxplayouts;
Expand Down

0 comments on commit 30a8416

Please sign in to comment.