aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/h48.md15
-rw-r--r--src/solvers/h48/solve.h27
2 files changed, 30 insertions, 12 deletions
diff --git a/doc/h48.md b/doc/h48.md
index 6b31503..30b5171 100644
--- a/doc/h48.md
+++ b/doc/h48.md
@@ -334,12 +334,15 @@ encountered in this step is of course added to the list of solutions.
334#### Heuristically sorting tasks 334#### Heuristically sorting tasks
335 335
336The tasks described in the previous paragraph (multi-threading) are 336The tasks described in the previous paragraph (multi-threading) are
337initially searched in an arbitrary order. However, after searching at a 337initially searched in an arbitrary order. However, after searching
338sufficient depth, we have gathered some data that allows us to make some 338at a sufficient depth, we have gathered some data that allows us to
339heuristical improvements: the tasks that leads to visiting more positions 339make some heuristical improvements: the tasks that leads to visiting
340(or in other words, where we go over the estimated lower bounds less 340more positions (or in other words, where we go over the estimated lower
341often), are more likely to yield the optimal solution. Thus we sort the 341bounds less often), are more likely to yield the optimal solution. Thus
342tasks based on this. 342we sort the tasks based on this, adjusting by a small factor due to the
343fact that sequences ending in U, R or F moves have more continuations
344than those ending in D, L or B moves - as we don't allow, for example,
345both U D and D U, but only the former.
343 346
344Preliminary benchmark show a performance improvement of around 40% 347Preliminary benchmark show a performance improvement of around 40%
345when searching a single solution. When searching for multiple optimal 348when searching a single solution. When searching for multiple optimal
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h
index 42d15f8..6026ec7 100644
--- a/src/solvers/h48/solve.h
+++ b/src/solvers/h48/solve.h
@@ -12,7 +12,7 @@
12typedef struct { 12typedef struct {
13 cube_t cube; 13 cube_t cube;
14 uint8_t moves[H48_STARTING_MOVES]; 14 uint8_t moves[H48_STARTING_MOVES];
15 int64_t nodes_visited; 15 int64_t rank;
16} solve_h48_task_t; 16} solve_h48_task_t;
17 17
18typedef struct { 18typedef struct {
@@ -283,6 +283,7 @@ STATIC void *
283solve_h48_runthread(void *arg) 283solve_h48_runthread(void *arg)
284{ 284{
285 int i, j; 285 int i, j;
286 uint8_t lastmove;
286 int64_t nprev; 287 int64_t nprev;
287 dfsarg_solve_h48_t *dfsarg; 288 dfsarg_solve_h48_t *dfsarg;
288 289
@@ -295,8 +296,6 @@ solve_h48_runthread(void *arg)
295 while (*dfsarg->status == NISSY_STATUS_PAUSE) 296 while (*dfsarg->status == NISSY_STATUS_PAUSE)
296 msleep(BASE_SLEEP_TIME); 297 msleep(BASE_SLEEP_TIME);
297 298
298 dfsarg->tasks[i].nodes_visited = 0;
299
300 solution_moves_reset(dfsarg->solution_moves); 299 solution_moves_reset(dfsarg->solution_moves);
301 memcpy(dfsarg->solution_moves->moves, 300 memcpy(dfsarg->solution_moves->moves,
302 dfsarg->tasks[i].moves, H48_STARTING_MOVES); 301 dfsarg->tasks[i].moves, H48_STARTING_MOVES);
@@ -317,7 +316,20 @@ solve_h48_runthread(void *arg)
317 316
318 solve_h48_dfs(dfsarg); 317 solve_h48_dfs(dfsarg);
319 318
320 dfsarg->tasks[i].nodes_visited = dfsarg->nodes_visited - nprev; 319 /*
320 We compute the "rank" of each taks, which is used in the next
321 step of the IDFS to sort them. This heuristically leads us
322 faster to a solution. The rank is computed by taking the
323 number of nodes visited, adjusted by a factor of about
324 sqrt(2)/sqrt(3) because there are more sequences starting with
325 U, R and F than with D, L and B, as we don't allow e.g. both
326 U D and D U, but only U D.
327 This trick was suggested by Chen Shuang, the implementation is
328 inspired by Andrew Skalski's vcube.
329 */
330 lastmove = dfsarg->tasks[i].moves[H48_STARTING_MOVES-1];
331 dfsarg->tasks[i].rank = (dfsarg->nodes_visited - nprev) *
332 (movebase(lastmove) % 2 == 0 ? 47525 : 58206);
321 nprev = dfsarg->nodes_visited; 333 nprev = dfsarg->nodes_visited;
322 } 334 }
323 335
@@ -417,8 +429,11 @@ solve_h48_log_solutions(solution_list_t s[static 1], size_t e)
417STATIC int 429STATIC int
418solve_h48_compare_tasks(const void *x, const void *y) 430solve_h48_compare_tasks(const void *x, const void *y)
419{ 431{
420 return ((solve_h48_task_t *)y)->nodes_visited 432 int64_t nodes_x = ((solve_h48_task_t *)x)->rank;
421 - ((solve_h48_task_t *)x)->nodes_visited; 433 int64_t nodes_y = ((solve_h48_task_t *)y)->rank;
434
435 /* Same as returning nodes_y - nodes_x, but avoids overflow */
436 return (nodes_x < nodes_y) - (nodes_x > nodes_y);
422} 437}
423 438
424STATIC int64_t 439STATIC int64_t

Generated with cgit - Back to sebastiano.tronto.net