gochatai/pachi_py/pachi/uct/search.c
/* Determine whether we should terminate the search early. */
Determine whether we should terminate the search early.
Determine whether we should terminate the search early .
static bool
uct_search_stop_early(struct uct *u, struct tree *t, struct board *b,
		struct time_info *ti, struct time_stop *stop,
		struct tree_node *best, struct tree_node *best2,
		int played, bool fullmem)
{
	if (fullmem)
		return true;
	double elapsed = 0.0;
	if (ti->dim == TD_WALLTIME) {
		elapsed = time_now() - ti->len.t.timer_start;
		if (elapsed < TREE_BUSYWAIT_INTERVAL) return false;
	}
	bool time_indulgent = (!ti->len.t.main_time && ti->len.t.byoyomi_stones == 1);
	if (best2 && ti->dim == TD_WALLTIME
	    && played >= PLAYOUT_EARLY_BREAK_MIN && !time_indulgent) {
		double remaining = stop->worst.time - elapsed;
		double pps = ((double)played) / elapsed;
		double estplayouts = remaining * pps + PLAYOUT_DELTA_SAFEMARGIN;
		if (best->u.playouts > best2->u.playouts + estplayouts) {
			if (UDEBUGL(2))
				fprintf(stderr, "Early stop, result cannot change: "
					"best %d, best2 %d, estimated %f simulations to go (%d/%f=%f pps)\n",
					best->u.playouts, best2->u.playouts, estplayouts, played, elapsed, pps);
			return true;
		}
	}
	if (best->u.playouts >= PLAYOUT_EARLY_BREAK_MIN
	    && (ti->dim != TD_WALLTIME || elapsed > TIME_EARLY_BREAK_MIN)
	    && tree_node_get_value(t, 1, best->u.value) >= u->sure_win_threshold) {
		return true;
	}
	return false;
}
static bool uct_search_stop_early ( struct uct * u , struct tree * t , struct board * b , struct time_info * ti , struct time_stop * stop , struct tree_node * best , struct tree_node * best2 , int played , bool fullmem ) { if ( fullmem ) return true ; double elapsed = 0.0 ; if ( ti -> dim == TD_WALLTIME ) { elapsed = time_now ( ) - ti -> len . t . timer_start ; if ( elapsed < TREE_BUSYWAIT_INTERVAL ) return false ; } bool time_indulgent = ( ! ti -> len . t . main_time && ti -> len . t . byoyomi_stones == 1 ) ; if ( best2 && ti -> dim == TD_WALLTIME && played >= PLAYOUT_EARLY_BREAK_MIN && ! time_indulgent ) { double remaining = stop -> worst . time - elapsed ; double pps = ( ( double ) played ) / elapsed ; double estplayouts = remaining * pps + PLAYOUT_DELTA_SAFEMARGIN ; if ( best -> u . playouts > best2 -> u . playouts + estplayouts ) { if ( UDEBUGL ( 2 ) ) fprintf ( stderr , " " " \n " , best -> u . playouts , best2 -> u . playouts , estplayouts , played , elapsed , pps ) ; return true ; } } if ( best -> u . playouts >= PLAYOUT_EARLY_BREAK_MIN && ( ti -> dim != TD_WALLTIME || elapsed > TIME_EARLY_BREAK_MIN ) && tree_node_get_value ( t , 1 , best -> u . value ) >= u -> sure_win_threshold ) { return true ; } return false ; }
Determine whether we should terminate the search early.
Determine whether we should terminate the search early .
/* If the memory is full, stop immediately. Since the tree
	 * cannot grow anymore, some non-well-expanded nodes will
	 * quickly take over with extremely high ratio since the
	 * counters are not properly simulated (just as if we use
	 * non-UCT MonteCarlo). */ /* (XXX: A proper solution would be to prune the tree
	 * on the spot.) */ /* Think at least 100ms to avoid a random move. This is particularly
	 * important in distributed mode, where this function is called frequently. */ /* Break early if we estimate the second-best move cannot
	 * catch up in assigned time anymore. We use all our time
	 * if we are in byoyomi with single stone remaining in our
	 * period, however - it's better to pre-ponder. */ /* Early break in won situation. */