From cube-lovers-errors@mc.lcs.mit.edu Thu Jan 7 13:53:48 1999 Return-Path: Received: from sun28.aic.nrl.navy.mil (sun28.aic.nrl.navy.mil [132.250.84.38]) by mc.lcs.mit.edu (8.9.1a/8.9.1-mod) with SMTP id NAA29288 for ; Thu, 7 Jan 1999 13:53:47 -0500 (EST) Precedence: bulk Errors-To: cube-lovers-errors@mc.lcs.mit.edu Date: Wed, 6 Jan 1999 23:02:32 -0500 From: michael reid Message-Id: <199901070402.XAA18140@cauchy.math.brown.edu> To: cube-lovers@ai.mit.edu Subject: Re: Your Optimal Solver herbert writes > You use the lines similar to > > if (p_node[1].remain_depth > which means tree pruning and we apply the next move in this depth. > > An analysis shows, that the case (p_node[1].remain_depth happens quite often (while p_node[1].remain_depth for n>1 except at the very beginning of the search). In this case, if we > for example had applied the move R, we need not to check R2 and R' any > more but we can continue with another axis. interesting idea. when i get a chance i'll see if i can also get a performance boost using this idea. for quarter turns, there is something similar i can do, but this is only because of the method i used for quarter turns. namely, i don't ever do R R , instead, i do R2 and count it as two moves. if applying the move R results in a branch of the tree that gets pruned, then we do not have to try R2. however, if i used a different method for quarter turns, where i only make one move at a time, then the R2 branch would be a sub-branch of the R branch. thus it would be pruned automatically. this suggests that it might be better to use this latter method for searching the tree. (the only reason i didn't do this is that i wanted to use one function for both quarter turns and face turns.) another idea, suggested to me by rich korf, is to use the line if ((node.remain_depth < ELEVEN) && (node.remain_depth < DIST)) continue; /* prune this branch */ where ELEVEN is just the constant 11, and DIST is the macro to look into the big table for the distance of the current coset. if the first part of the expression is TRUE , then we evaluate the second part. in this case we did a tiny bit of extra work to evaluate the first part. but if the first part is FALSE , then we save some work by not looking into the table. we lose a little bit of pruning (there are some cosets at distance 12) but this is very small. rich explained (if i understood correctly) that every look into the big table is expensive, because it will pull a small piece of the table into cache. but this piece is unlikely to be used again soon, so it probably displaced some more useful stuff from cache. the DIST macro is also a complicated expression, so it is also expensive in that way. when i tried this, i didn't measure any significant performance boost (< 1%). but the cache benefit would be more noticeable for longer searches, so perhaps my test was just too short. it also depends upon your DIST macro (or corresponding code); i think rich had more processing to do besides looking into the table. and it may also depend on the size of your secondary cache. i do have this in my huge optimal solver, so it must have given some improvement there, but i don't remember how much. i had to do lots of tweaking for performance issues on this program. herbert, if you have a program that uses the exact same coordinates as mine, you will find it amusing to try the positions * position created by R2 F' R2 F2 D2 F' R2 F2 R2 D2 F' D2 F' * inverse of the above position. and noticing the huge difference. because of this, i thought about maybe solving either the input position or its inverse, depending upon which should be faster. my experiments showed that it wasn't easy to predict which would be easier by looking only at the distances of the 3 initial cosets. but perhaps doing a mini-search on each, and looking at how many nodes they spawn would give a better guess. of course, we can't expect to get the kind of performance boost suggested by the extreme example above, but we might get something. then i had a more ambitious idea: maybe we could prune the search tree by having the program realize "the inverse of this position is too far from start". the conclusion i eventually arrived at was that it wouldn't be possible to keep track of the coset of the inverses by using transformation tables. so this idea probably won't work. mike