diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-06-18 13:40:00 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-06-18 13:40:00 +0200 |
| commit | 0e334e8659deaf61c3eef57e8ccd171a5becedb3 (patch) | |
| tree | 529fb7bc5d0aed1d6b422f5ad6c9de0f05df3f44 /src/solvers | |
| parent | b3d1ca3d503f3d525f653067b3555e86048bfdac (diff) | |
| download | nissy-core-0e334e8659deaf61c3eef57e8ccd171a5becedb3.tar.gz nissy-core-0e334e8659deaf61c3eef57e8ccd171a5becedb3.zip | |
Trick fix
Diffstat (limited to 'src/solvers')
| -rw-r--r-- | src/solvers/h48/solve.h | 27 |
1 files changed, 21 insertions, 6 deletions
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 @@ | |||
| 12 | typedef struct { | 12 | typedef 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 | ||
| 18 | typedef struct { | 18 | typedef struct { |
| @@ -283,6 +283,7 @@ STATIC void * | |||
| 283 | solve_h48_runthread(void *arg) | 283 | solve_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) | |||
| 417 | STATIC int | 429 | STATIC int |
| 418 | solve_h48_compare_tasks(const void *x, const void *y) | 430 | solve_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 | ||
| 424 | STATIC int64_t | 439 | STATIC int64_t |
