aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-10-01 19:20:16 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-10-01 19:20:16 +0200
commit8d3fe446815a1631876e4170747bc6cb03a6bbf8 (patch)
treeae83f73e14d3699c6cf89cbf812ed1c8a9956698 /doc
parente3d0efaebd00af412602ae71062d24d7977e443a (diff)
downloadnissy-core-8d3fe446815a1631876e4170747bc6cb03a6bbf8.tar.gz
nissy-core-8d3fe446815a1631876e4170747bc6cb03a6bbf8.zip
Updated h48 doc
Diffstat (limited to '')
-rw-r--r--doc/h48.md103
1 files changed, 81 insertions, 22 deletions
diff --git a/doc/h48.md b/doc/h48.md
index f6fec2e..323453a 100644
--- a/doc/h48.md
+++ b/doc/h48.md
@@ -132,7 +132,7 @@ The H48 solver uses a target group that is invariant under all 48
132symmetries. This group is defined as follows: 132symmetries. This group is defined as follows:
133 133
134* Each corner is placed in the *corner tetrad* it belongs to, and it 134* Each corner is placed in the *corner tetrad* it belongs to, and it
135 is oriented. Here by corner tetrad we means one of the two sets of 135 is oriented. Here by corner tetrad we mean one of the two sets of
136 corners {UFR, UBL, DFL, DBR} and {UFL, UBR, DFR, DBL}. For a corner 136 corners {UFR, UBL, DFL, DBR} and {UFL, UBR, DFR, DBL}. For a corner
137 that is placed in its own tetrad, the orientation does not depend on 137 that is placed in its own tetrad, the orientation does not depend on
138 the reference axis chosen, and an oriented corner can be defined 138 the reference axis chosen, and an oriented corner can be defined
@@ -171,17 +171,17 @@ is a little too much for most personal computers.
171 171
172One can wonder if it is possible to use a coordinate that considers 172One can wonder if it is possible to use a coordinate that considers
173the orientation of only *some* of the edges, which we may call **h1** 173the orientation of only *some* of the edges, which we may call **h1**
174to **h10**. Such coordinates do exist, but it is not invariant under the 174to **h10**. Such coordinates do exist, but they are not invariant under
175full symmetry group: indeed an edge whose orientation we keep track of 175the full symmetry group: indeed an edge whose orientation we keep track
176could be moved to any of the untracked edges' positions by one of the 176of could be moved to any of the untracked edges' positions by one of
177symmetries, making the whole coordinate ill-defined. 177the symmetries, making the whole coordinate ill-defined.
178 178
179It is however possible to compute the symmetry-reduced pruning tables 179It is however possible to compute the symmetry-reduced pruning tables
180for these coordinates. One way to construct them is by taking the **h11** 180for these coordinates. One way to construct them is by taking the **h11**
181pruning table and "forgetting" about some of the edge orientation values, 181pruning table and "forgetting" about some of the edge orientation values,
182collapsing 2 (or a power thereof) values to one by taking the minimum. 182collapsing 2 (or a power thereof) values to one by taking the minimum.
183It is also possible to compute these tables directly, as explained in 183It is also possible to compute these tables directly, as explained in
184the **Pruning table computation** section below (work in progress). 184the **Pruning table computation** section below.
185 185
186### Coordinate computation for pruning value estimation 186### Coordinate computation for pruning value estimation
187 187
@@ -220,9 +220,6 @@ Once we have computed the full h0 coordinate, we can access the correct
220entry in the full pruning table. As mentioned above, the pruning table 220entry in the full pruning table. As mentioned above, the pruning table
221can be one of three kinds: 221can be one of three kinds:
222 222
223(Work in progress - the only kind of table currently implemented is
224the 4 bits per entry table)
225
226* 4 bits per entry, or `k4`: In this case the pruning value (between 0 223* 4 bits per entry, or `k4`: In this case the pruning value (between 0
227 and 15) can be simply read off the table. 224 and 15) can be simply read off the table.
228* 2 bits per entry, or `k2`: Tables of this kind work as described by 225* 2 bits per entry, or `k2`: Tables of this kind work as described by
@@ -236,7 +233,6 @@ the 4 bits per entry table)
236 cannot take b as a lower bount. Instead we have to use a pruning value from 233 cannot take b as a lower bount. Instead we have to use a pruning value from
237 another table, for example the corner-only table mentioned in the previous 234 another table, for example the corner-only table mentioned in the previous
238 section, or a completely new one. 235 section, or a completely new one.
239 (Work in progress - `k2` tables not available in the code yet)
240* 1 bit per entry, or `k1`: With one bit per entry, the only information we 236* 1 bit per entry, or `k1`: With one bit per entry, the only information we
241 can get from the pruning table is wether or not the current position 237 can get from the pruning table is wether or not the current position
242 requires more or fewer moves than a fixed base value b. This can still be 238 requires more or fewer moves than a fixed base value b. This can still be
@@ -249,8 +245,6 @@ the 4 bits per entry table)
249After computing the pruning value, there are a number of different tricks 245After computing the pruning value, there are a number of different tricks
250that can be used to improve the estimation. 246that can be used to improve the estimation.
251 247
252(Work in progress - the following techniques are not implemented yet)
253
254#### Inverse estimate 248#### Inverse estimate
255 249
256A cube position and its inverse will, in general, give a different 250A cube position and its inverse will, in general, give a different
@@ -299,8 +293,6 @@ Other possible (low-level) optimizations include:
299 is expensive. We can avoid doing that (for the inverse pruning value 293 is expensive. We can avoid doing that (for the inverse pruning value
300 estimate) if we bring along both the normal and the inverse cube during 294 estimate) if we bring along both the normal and the inverse cube during
301 the search, and we use *premoves* to apply moves to the inverse scramble. 295 the search, and we use *premoves* to apply moves to the inverse scramble.
302 (Work in progress - premoves are not implemented yet, but it will take
303 little work to add them)
304* **Multi-threading (multiple scrambles)**: It is easy to parallelize this 296* **Multi-threading (multiple scrambles)**: It is easy to parallelize this
305 algorithm when solving multiple cubes at once, by firing up multiple 297 algorithm when solving multiple cubes at once, by firing up multiple
306 instances of the solver. It is important to make sure that the same 298 instances of the solver. It is important to make sure that the same
@@ -314,17 +306,84 @@ Other possible (low-level) optimizations include:
314 306
315## Pruning table computation 307## Pruning table computation
316 308
317### The h0 table 309### 4 bits tables for h0 and h11
310
311Computing the pruning table for a "real" h48 coordinate, that **h0**
312or **h11**, using 4 bits per entry is quite simple. The method currently
313implemented works as follows.
314
315First, we set the value of the solved cube's coordinate to 0 and every
316other entry to 15, the largest 4-bit integer. Then we iteratively scan
317through the table and compute the coordinates at depth n+1 from those at
318depth n as follows: for each coordinate at depth n, we compute a valid
319representative for it, we apply each of the possible 18 moves to it, and
320we set their value to n+1. Once the table is filled or we have reached
321depth 15, we stop (there are no **h0** coordinates at depth 16 or more,
322but I currently don't know if this is the case for **h11**).
323
324Unfortunately what I described above is an oversimplification: one
325also must take into account the case where the corner coordinate is
326self-symmetric, and handle it accordingly by making sure that every
327symmetric variation of the same coordinate has its value set at the
328right iteration.
329
330When this algorithm reaches the last few iterations, the coordinates at
331depth n are many more than those whose depth is still unknown. Therefore
332it is convenient to look at the unset coordinate and check if they have
333any neighbor whose depth is i; if so, we can set such a coordinate to i+1.
334Thanks to [torchlight](https://github.com/torchlight) for suggesting
335this optimization.
336
337Finally, this algorithm can be easily parallelized by dividing the set
338of coordinates into separate sections, but one must take into account
339that a coordinate and its neighbors are usually not in the same section.
340
341This method is currently implemented only for **h0**, since the 4 bits
342table for **h11** would require around 115GB of RAM to compute, and I
343don't have this much memory.
344
345### 2 bits tables with for h0 and h11
346
347(Work in progress - currently I there is no specialized routine for
348computing 2 bits table for "real" coordinates; instead, an optimized
349version of the generic method explained below is used)
318 350
319TODO - short explanation of how this is computed 351### A generic method for intermediate coordinates (from h1 to h10)
320 352
321### The intermediate tables (h1, ... h10) 353(Work in progress - this method is quite slow and it may be replaced
354by a better algorithm in the future)
322 355
323TODO - explain why these are more complicated (if one does not 356Computing the pruning tables for intermediate coordinates is not as
324want to compute the full **h11** table first) 357simple. The reason is that these coordinates are not invariant under
358the 48 transformations of the cube, but we are treating them as such.
359Take for example the case of **h10**. Each **h10** coordinate is
360represented by either of two **h11** coordinates: the one where the 11th
361edge is correctly oriented and the one where this edge is flipped (of
362course, the orientation of the 12th edge can be deduced from the parity
363of the orientation of the other 11). We can take any cube whose **h11**
364coordinate is one of these two to represent our **h10** coordinate, but
365the set of neighbors will change depending on which representative we
366picked. In other words: if I take one of the two cubes and make a move,
367the position reached is not necessarily obtainable by applying a move
368to the other cube. This means that the same algorithm that we described
369for the "real coordinate" case cannot be applied here.
325 370
326Work in progress - these tables are not implemented yet. 371It is still possible to do a brute-force depth-first seach to fill
372these tables. To make it reasonably fast, we apply a couple of
373optimizations. First of all, we restrict ourselves to computing a 2 bits
374table, so we can stop the search early.
327 375
328### The h11 table 376The second optimization we employ consists in pre-computing all possible
377**h11** coordinates at a fixed depth, and storing their depth in a hash
378map indexed by their **h11** coordinate value. This way we do not have
379to brute-force our way through from depth 0, and it make this method
380considerably faster. Unfortunately, since the number of coordinates
381at a certain depth increases exponentially with the depth, we are for
382now limited at storing the coordinates at depth 8. (Work in progress -
383we may experiment with depth 9 in the future)
329 384
330Work in progress - this tables is not implemented yet. 385This method works for the "real" coordinates **h0** and **h11** as well.
386Moreover, in this case one can optimize it further by avoiding to repeat
387the search from a coordinate that has already been visited. (Work
388in progress - this method will be replaced in the future by a more
389efficient one)

Generated with cgit - Back to sebastiano.tronto.net