Moderator: Andres Valverde
H.G.Muller wrote:If you search another move before the one causing the fail high, this need not be wasted effort
H.G.Muller wrote:...the first search might increase alpha a lot, so that the search on the failing move can be done with a much narrower window, making that subtree much more heavily pruned...
Gian-Carlo Pascutto wrote:A common method of measuring move ordering performance is to check the ration "fail high on first move / fail high".
Several people have correctly observed that this is in fact a pretty bad way to measure, because there might be many moves that would fail high, and in that case you want the smallest tree.
It seems to me that the only kind of positions where you can really measure this is at PV nodes.
So, the move ordering performance would be: "number of times the first move at a PV node was indeed the best move".
There might be a sensible definition at alpha nodes too; if we have a fail high there, it should be at the first move, and no other move should fail high.
It's funny that the only places where you can measure is where most people don't do it.
Did anyone measure this way? What rates do you get in what positions?
Uri Blass wrote:if I do a change in move ordering than testing if the change is good is simply by test suites.
If the result in test suites is better than probably the change is a good change.
Steve Maughan wrote:H.G.Muller wrote:If you search another move before the one causing the fail high, this need not be wasted effort
I agree that an earlier search can have *some* benefit but I think in *all* cases it would be better to search the move that gives the cutoff first. Effectively you're advocating sub-optimal move ordering.H.G.Muller wrote:...the first search might increase alpha a lot, so that the search on the failing move can be done with a much narrower window, making that subtree much more heavily pruned...
I would also add that the number of nodes where alpha is increased and there is then a subsequent beta cutoff is tiny (I'm guessing < 0.001%), at least for a PVS search.
H.G.Muller wrote:[snip]
Well, I am advocating that some sub-optimal move orderings are better than others.
[snip]
----a +1 Minimax
|---b +1
----A---c +1
| /--d -1
R---B---e -1
| \--f -1
|---C---g -3
| |---h -3
| ----j -3
----D---k 0
----a +1 Alpha-Beta
|---b +1 with perfect move ordering
----A---c +1
| /--d -3
R---B-x
| \x
|---C---g -3
| |-x
| --x
----D---k 0
----d -3 Alpha-Beta
|---e -3 with 1 wrong move sorted in front for ply 1
----B---f -3
| /--a +1
R---A---b +1
| \--c +1
|---C---g -3
| |-x
| --x
----D---k 0
----D---k 0 Alpha-Beta
| ----d -3 with simple sub-optimal move sorted in front
| |-x
----B-x
| /--a +1
R---A---b +1
| \--c +1
----C---g -3
|-x
--x
H.G.Muller wrote:But never better than what?
H.G.Muller wrote:A 2-ply search tree sprouts from root position R. From R there is one move that leads to a much simplified position D, from where each side has only very few moves (in this example only one). Many other moves, however, keep the situation complicated, and in these complex positions many moves are possible. (Many = three here, for ease of drawing.)
Without any cutoffs, there are 10 end leaves after 2 ply (a...k). With alpha-beta and perfect move ordering the best move, leading to position A, is searched first, and all answers (a,b,c) have to be considered to conclude that its score is +1. When moves (to positions) B and C are tried after that, the first answer (d and g, respectively) is enough to refute them compared to the +1 score, and cause a fail high on ply 2. So e,f,h and j are not searched. In the D branch there is nothing to cut off, because it was the last (and only) reply that caused the fail high.
In the third case, the move ordering is imperfect, and B is sorted beore A in ply 1. So now B is best at the moment it is searched, and all replies (d,e,f) hae to be searched to conclude that its score is -3. To find that A supersedes B as best move, al its replies (a,b,c) have to be searched on ply 2. So the only fail highs now occur on searching C (h,k).
Now suppose I intentionally sort move D in fromt, not based on its suspected value, but on the (easily recognized) property that it leads to a sub-tree with small branching. Then the move B, that was erroneously picked as next to search, will see a fail high in the first considered reply (d), so that 2 branches (e,f) are cut that were not cut in the third case.
Conclusion: one more sub-optima move sorted in front makes the (fixed-depth) tree smaller (by 2 end leaves).
Of course 'many'could have meant 30 in stead of 3, so that 29 leaves were pruned from the tree in stead of 2. And the drawn part of the tree could have been the first two ply of an 8-ply search, so that every end-leave that was cut was in fact a 6-ply subtree with each thousands of end leaves.
I could give you many more examples, also where the move ordering on ply 0 was perfect, where sorting the suboptimal D in front of the otherwise perfectly ordered A,B,C would result in savings on ply 4 (in the subtree starting at a) because of imperfect ordering of the moves on ply 3. But they are a bit difficut to draw, because they need 4 plies...
Steve Maughan wrote:It seems that the formatting got messed up - hopefully I've corrected it at the end of my message.H.G.Muller wrote:But never better than what?
Sub-optimal move ordering never gives a tree size small than optimal move ordering.
Steve Maughan wrote:Of course some sub-optimal more ordering schemes are better than others - in your case (4) is better than (3).
Gian-Carlo Pascutto wrote:A common method of measuring move ordering performance is to check the ration "fail high on first move / fail high".
Several people have correctly observed that this is in fact a pretty bad way to measure, because there might be many moves that would fail high, and in that case you want the smallest tree.
It seems to me that the only kind of positions where you can really measure this is at PV nodes.
So, the move ordering performance would be: "number of times the first move at a PV node was indeed the best move".
There might be a sensible definition at alpha nodes too; if we have a fail high there, it should be at the first move, and no other move should fail high.
It's funny that the only places where you can measure is where most people don't do it.
Did anyone measure this way? What rates do you get in what positions?
if value > best
if alpha != beta - 1
if first move , first_move_count ++;
else if this_node_not_failed_best_condition
num_pvnode_count ++;
first_move_count --;
this_node_not_failed_best_condition =1
and final stat :
(first_move_count * 100) / (num_pvnode_count + first_move_count)
if value > best
if alpha != beta - 1
num_pvnode_count++;
if first move , first_move_count ++;
else if this_node_not_failed_best_condition
this_node_not_failed_best_condition =1
and final stat :
(first_move_count * 100) / (num_pvnode_count + 1)
Gian-Carlo Pascutto wrote:I would write it like this:
- Code: Select all
if value > best
if alpha != beta - 1
num_pvnode_count++;
if first move , first_move_count ++;
else if this_node_not_failed_best_condition
this_node_not_failed_best_condition =1
and final stat :
(first_move_count * 100) / (num_pvnode_count + 1)
H.G.Muller wrote:Well, I am advocating that some sub-optimal move orderings are better than others. Your truth that optimal move-ordering is best falls in the same category as "smoke detectors are a waste of money, it is better not to cause fires"... Rock climbers 'waste' a lot of effort hammering in anchors that they don't need to get to the top, to secure their savety lines. In an imperfect world you simply get better over-all performance by investing in precautions.
So in the case that the move ordering on ply 3 is perfect, there is indeed nothing to be gained by upping alpha on an earlier move in ply 1. None of the answers on ply 4 will be good enogh to cause a faiil high, even with the lower value of beta you will have their. Deep cutoffs will never occur if the move ordering is perfect. But in practice your engine suffers a lot if you don't implement them.
H.G.Muller wrote:If I want to judge the quality of my move sorting I count the nodes actually visited, and compare that to the size of the minimal tree required to judge that the move found was the best. To obtain the latter I redo the search with the window closed around the value that the earlier search found, and I added code to pass the number of required nodes down to the root: for alpha or PV nodes this is the sum of the corresponding values of all spawned subtrees + 1, for a beta node it counts only the subtree that caused the fail high + 1. This is not perfect, because there is no guarantee that there was no smaller subtree (not yet examined) that would also have caused a fail high. But it should be a good indication.
To be really precise I would have to search all moves in every node, i.e. continue searching after a fail high to look for cheaper fail highs, and for a deep tree this is so expensive that it is usually not feasible. (According to theory this squares the number of nodes in the tree...) So by comparing the numbers I measure how efficiently the program picks the best move first in PV nodes (in alpha nodes sorting has no effect on the tree size), without knowing anything about how clever it is in choosing the cheapest move to cause a fail high from all moeves that do cause it.
Return to Programming and Technical Discussions
Users browsing this forum: No registered users and 33 guests