[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: computer-go: [Question] Alpha-Beta Pruning & Null Move
From: "Thomas Thomsen" <thomas@xxxxxxxxxxxxxxxxx>
Reply-To: computer-go@xxxxxxxxxxxxxxxxx
Don Dailey wrote:
>The tricky part is defining "happy." Fortunately, "happy" has a very
>precise definition. It simply means that given 2 moves in a row, can
>I achieve a score good enough to achieve at least my expectation? If
>you can, you are "happy." In a losing position, you can still be
>"happy" given this definition because you expectations are
>appropriately lowered! Your "expectation" is the "alpha" part of
>"alpha/beta pruning" or put another way your proven lower bound.
Regarding null-moves, I think it helps to distinguish between two kinds of
applications: (a) uniform search trees, and (b) non-uniform search trees.
I'm not clear on the definition of uniform. I thought it was an
idealized tree with the same branching factor AND fixed depth. Go is
not this nor is chess. In Go, you might imagine using fixed depth
search but I don't see that making any difference for this discussion.
(a) In Go, the global evaluation function produces a typical uniform search
tree with an average branching factor of, say, 250. As pointed out, "good"
and "bad" depends on the context (in alpha-beta terminology: the values of
alpha and beta). Regarding the global evaluation function, null-move pruning
only starts to be meaningful when this tree is searched to depth 5 plies or
more (remember that the null-moves are searched with a depth-reduction of
2-3 plies).
Null-move prunning is meaningful with a 2 ply search. A depth
reduction factor of 2 or 3 plys would make the reductions happen after
1 move and call for a null move followed by a negative depth seach!
Since you cannot do a negative ply search, you round up to the closest
thing, zero ply. In other words, when you are this close to leaf
nodes you are reduced to assuming that whoever is on the move, can at
least hold the currently calculated static score. This also means you
can take cutoffs on the 2nd ply if the score for the side to move is
already above beta (or his upper bound expectation) which in GO, is
probably reasonable given the assumption that it never hurts to be on
the move!
This may be a horrible thing, I don't know. I'm only saying that the
algorithm is intact.
In Chess, you deal with the same exact situation, and programs benefit
even with 2 ply searches, although the benefit is minor. But in Chess
this case becomes a quies search on the final ply with colors
reversed.
My own chess programs use a different approach. Although I don't do
null move pruning this close to leaf nodes, I do something roughly
equivalent, a static exchange evaluator is applied when the null move
depth would be zero or less. What I do is just an optimization, using
a purer form of null move is perfectly valid.
I don't know if global null move will ever be useful in Go. As I've
said before, it's not hard for me to imagine that it might now work so
well in Go. It will produce severely prunned trees however, there is
absolutely no question about that.
I am interested myself in knowing if it "works" and maybe I will
explore this myself at some point. To me it "works" if it can be
shown to be better with global searching than global searching would
be without null move prunning. I wouldn't be trying to prove that
global searching works if I did this, only if null move prunning HELPS
global searching.
Don
(b) However, for local tactical searches, non-uniform search trees are
abundant. The goal of killing a block or connecting two blocks produces a
typical non-uniform search tree, because after the block gets taken off the
board or the two blocks are connected, the local game ends. Such
non-uniformity is highly exploitable by null-move techniques.
For instance, in the context of a ladder, the attacker only plays moves so
that -- if the defender passes -- the attacker can follow up by taking the
stones off the board. That produces a search-tree of threat-order 1. What
I've been fumbling with is that this idea can be generalized to any
threat-order (so-called lambda-order). For instance, in a loose ladder
(threat-order 2), the attacker only plays moves so that -- if the defender
passes -- the attacker can follow up by killing the stones in a normal
ladder. And in a loose loose ladder (threat-order 3), the attacker only
plays moves so that -- if the defender passes -- the attacker can follow up
by killing the stones in a loose ladder. And so on. This saves an enormous
amount of work, but still guarantees exactness.
Note that (b) doesn't operate with alpha's and beta's. This is because
obtaining the goal is thought of as an irreversible feat: if a block can be
captured in 5 plies, there is no risk of it being de-captured when looking a
few plies deeper. Similarly, if a block is connected, it cannot be
de-connected deeper in the search tree. However, (a) is different. It may be
possible to achieve a very good evaluation at depth 5 plies, but no matter
how good the evaluation value is, nothing can guarantee that the result is
not reverted when looking a few plies deeper.
Best regards,
-Thomas Thomsen