diff options
Diffstat (limited to 'src/solvers/h48/solve.h')
| -rw-r--r-- | src/solvers/h48/solve.h | 78 |
1 files changed, 41 insertions, 37 deletions
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index bf10723..ad66fd4 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -13,6 +13,7 @@ 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 rank; | 15 | int64_t rank; |
| 16 | uint64_t tmask[H48_STARTING_MOVES]; | ||
| 16 | } solve_h48_task_t; | 17 | } solve_h48_task_t; |
| 17 | 18 | ||
| 18 | typedef struct { | 19 | typedef struct { |
| @@ -22,6 +23,7 @@ typedef struct { | |||
| 22 | int8_t target_depth; | 23 | int8_t target_depth; |
| 23 | solution_moves_t *solution_moves; | 24 | solution_moves_t *solution_moves; |
| 24 | solution_settings_t *solution_settings; | 25 | solution_settings_t *solution_settings; |
| 26 | const uint64_t *tmask; | ||
| 25 | solution_list_t *solution_list; | 27 | solution_list_t *solution_list; |
| 26 | int8_t lb_normal; | 28 | int8_t lb_normal; |
| 27 | int8_t lb_inverse; | 29 | int8_t lb_inverse; |
| @@ -55,6 +57,7 @@ typedef struct { | |||
| 55 | int8_t minmoves; | 57 | int8_t minmoves; |
| 56 | int8_t maxmoves; | 58 | int8_t maxmoves; |
| 57 | int8_t *shortest_sol; | 59 | int8_t *shortest_sol; |
| 60 | uint64_t tmask[H48_STARTING_MOVES]; | ||
| 58 | } dfsarg_solve_h48_maketasks_t; | 61 | } dfsarg_solve_h48_maketasks_t; |
| 59 | 62 | ||
| 60 | STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned, | 63 | STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned, |
| @@ -69,7 +72,7 @@ STATIC void *solve_h48_runthread(void *); | |||
| 69 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); | 72 | STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); |
| 70 | STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t); | 73 | STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t); |
| 71 | STATIC int solve_h48_compare_tasks(const void *, const void *); | 74 | STATIC int solve_h48_compare_tasks(const void *, const void *); |
| 72 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, | 75 | STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint64_t, uint8_t, |
| 73 | uint8_t, uint64_t, const unsigned char *, size_t, char *, | 76 | uint8_t, uint64_t, const unsigned char *, size_t, char *, |
| 74 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); | 77 | long long [static NISSY_SIZE_SOLVE_STATS], int (*)(void *), void *); |
| 75 | 78 | ||
| @@ -208,8 +211,8 @@ solve_h48_dfs(dfsarg_solve_h48_t arg[static 1]) | |||
| 208 | if (arg->target_depth != nm) | 211 | if (arg->target_depth != nm) |
| 209 | return 0; | 212 | return 0; |
| 210 | wrapthread_mutex_lock(arg->solutions_mutex); | 213 | wrapthread_mutex_lock(arg->solutions_mutex); |
| 211 | ret = appendsolution(arg->solution_moves, | 214 | ret = appendsolution(arg->solution_moves, H48_STARTING_MOVES, |
| 212 | arg->solution_settings, arg->solution_list); | 215 | arg->tmask, arg->solution_settings, arg->solution_list); |
| 213 | wrapthread_mutex_unlock(arg->solutions_mutex); | 216 | wrapthread_mutex_unlock(arg->solutions_mutex); |
| 214 | return ret; | 217 | return ret; |
| 215 | } | 218 | } |
| @@ -313,6 +316,7 @@ solve_h48_runthread(void *arg) | |||
| 313 | dfsarg->use_lb_inverse = false; | 316 | dfsarg->use_lb_inverse = false; |
| 314 | dfsarg->movemask_normal = MM18_ALLMOVES; | 317 | dfsarg->movemask_normal = MM18_ALLMOVES; |
| 315 | dfsarg->movemask_inverse = MM18_ALLMOVES; | 318 | dfsarg->movemask_inverse = MM18_ALLMOVES; |
| 319 | dfsarg->tmask = dfsarg->tasks[i].tmask; | ||
| 316 | 320 | ||
| 317 | solve_h48_dfs(dfsarg); | 321 | solve_h48_dfs(dfsarg); |
| 318 | 322 | ||
| @@ -341,7 +345,7 @@ solve_h48_runthread_end: | |||
| 341 | STATIC int64_t | 345 | STATIC int64_t |
| 342 | solve_h48_maketasks( | 346 | solve_h48_maketasks( |
| 343 | dfsarg_solve_h48_t solve_arg[static 1], | 347 | dfsarg_solve_h48_t solve_arg[static 1], |
| 344 | dfsarg_solve_h48_maketasks_t maketasks_arg[static 1], | 348 | dfsarg_solve_h48_maketasks_t mtarg[static 1], |
| 345 | solve_h48_task_t tasks[static H48_STARTING_CUBES], | 349 | solve_h48_task_t tasks[static H48_STARTING_CUBES], |
| 346 | int ntasks[static 1] | 350 | int ntasks[static 1] |
| 347 | ) | 351 | ) |
| @@ -353,59 +357,60 @@ solve_h48_maketasks( | |||
| 353 | cube_t backup_cube; | 357 | cube_t backup_cube; |
| 354 | solution_moves_t moves; | 358 | solution_moves_t moves; |
| 355 | 359 | ||
| 356 | if (equal(maketasks_arg->cube, SOLVED_CUBE)) { | 360 | if (equal(mtarg->cube, SOLVED_CUBE)) { |
| 357 | if (maketasks_arg->nmoves > maketasks_arg->maxmoves || | 361 | if (mtarg->nmoves > mtarg->maxmoves || |
| 358 | maketasks_arg->nmoves < maketasks_arg->minmoves || | 362 | mtarg->nmoves < mtarg->minmoves || |
| 359 | solutions_done(solve_arg->solution_list, | 363 | solutions_done(solve_arg->solution_list, |
| 360 | solve_arg->solution_settings, maketasks_arg->nmoves)) | 364 | solve_arg->solution_settings, mtarg->nmoves)) |
| 361 | return NISSY_OK; | 365 | return NISSY_OK; |
| 362 | 366 | ||
| 363 | solution_moves_reset(&moves); | 367 | solution_moves_reset(&moves); |
| 364 | moves.nmoves = maketasks_arg->nmoves; | 368 | moves.nmoves = mtarg->nmoves; |
| 365 | memcpy(moves.moves, | 369 | memcpy(moves.moves, mtarg->moves, mtarg->nmoves); |
| 366 | maketasks_arg->moves, maketasks_arg->nmoves); | ||
| 367 | 370 | ||
| 368 | appret = appendsolution(&moves, solve_arg->solution_settings, | 371 | appret = appendsolution(&moves, mtarg->nmoves, mtarg->tmask, |
| 369 | solve_arg->solution_list); | 372 | solve_arg->solution_settings, solve_arg->solution_list); |
| 370 | return appret < 0 ? appret : NISSY_OK; | 373 | return appret < 0 ? appret : NISSY_OK; |
| 371 | } | 374 | } |
| 372 | 375 | ||
| 373 | if (maketasks_arg->nmoves == H48_STARTING_MOVES) { | 376 | if (mtarg->nmoves == H48_STARTING_MOVES) { |
| 374 | tasks[*ntasks].cube = maketasks_arg->cube; | 377 | tasks[*ntasks].cube = mtarg->cube; |
| 375 | memcpy(tasks[*ntasks].moves, | 378 | memcpy(tasks[*ntasks].moves, mtarg->moves, |
| 376 | maketasks_arg->moves, H48_STARTING_MOVES); | 379 | H48_STARTING_MOVES * sizeof(uint8_t)); |
| 380 | memcpy(tasks[*ntasks].tmask, mtarg->tmask, | ||
| 381 | H48_STARTING_MOVES * sizeof(uint64_t)); | ||
| 377 | (*ntasks)++; | 382 | (*ntasks)++; |
| 378 | return NISSY_OK; | 383 | return NISSY_OK; |
| 379 | } | 384 | } |
| 380 | 385 | ||
| 381 | if (maketasks_arg->nmoves == 0) { | 386 | if (mtarg->nmoves == 0) { |
| 382 | mm = MM18_ALLMOVES; | 387 | mm = MM18_ALLMOVES; |
| 383 | } else { | 388 | } else { |
| 384 | m = maketasks_arg->moves[maketasks_arg->nmoves-1]; | 389 | m = mtarg->moves[mtarg->nmoves-1]; |
| 385 | mm = allowedmask[movebase(m)]; | 390 | mm = allowedmask[movebase(m)]; |
| 386 | } | 391 | } |
| 387 | 392 | ||
| 388 | maketasks_arg->nmoves++; | 393 | mtarg->tmask[mtarg->nmoves] = symmetry_mask(mtarg->cube); |
| 389 | backup_cube = maketasks_arg->cube; | 394 | |
| 395 | mtarg->nmoves++; | ||
| 396 | backup_cube = mtarg->cube; | ||
| 390 | for (m = 0; m < 18; m++) { | 397 | for (m = 0; m < 18; m++) { |
| 391 | if (!(mm & MM_SINGLE(m))) | 398 | if (!(mm & MM_SINGLE(m))) |
| 392 | continue; | 399 | continue; |
| 393 | maketasks_arg->moves[maketasks_arg->nmoves-1] = m; | 400 | |
| 394 | maketasks_arg->cube = move(backup_cube, m); | 401 | mtarg->moves[mtarg->nmoves-1] = m; |
| 395 | r = solve_h48_maketasks( | 402 | mtarg->cube = move(backup_cube, m); |
| 396 | solve_arg, maketasks_arg, tasks, ntasks); | 403 | r = solve_h48_maketasks(solve_arg, mtarg, tasks, ntasks); |
| 397 | if (r < 0) | 404 | if (r < 0) |
| 398 | return r; | 405 | return r; |
| 399 | 406 | ||
| 400 | /* Avoid symmetry-equivalent moves from the starting cube */ | 407 | /* Avoid symmetry-equivalent moves from the starting cube */ |
| 401 | if (maketasks_arg->nmoves == 1) | 408 | for (t = 0; t < NTRANS; t++) |
| 402 | for (t = 0; t < NTRANS; t++) | 409 | if (mtarg->tmask[mtarg->nmoves-1] & TM_SINGLE(t)) |
| 403 | if (solve_arg->solution_settings->tmask & | 410 | mm &= ~MM_SINGLE(transform_move(m, t)); |
| 404 | TM_SINGLE(t)) | ||
| 405 | mm &= ~MM_SINGLE(transform_move(m, t)); | ||
| 406 | } | 411 | } |
| 407 | maketasks_arg->nmoves--; | 412 | mtarg->nmoves--; |
| 408 | maketasks_arg->cube = backup_cube; | 413 | mtarg->cube = backup_cube; |
| 409 | 414 | ||
| 410 | return NISSY_OK; | 415 | return NISSY_OK; |
| 411 | } | 416 | } |
| @@ -441,7 +446,7 @@ solve_h48( | |||
| 441 | oriented_cube_t oc, | 446 | oriented_cube_t oc, |
| 442 | uint8_t minmoves, | 447 | uint8_t minmoves, |
| 443 | uint8_t maxmoves, | 448 | uint8_t maxmoves, |
| 444 | uint8_t maxsolutions, | 449 | uint64_t maxsolutions, |
| 445 | uint8_t optimal, | 450 | uint8_t optimal, |
| 446 | uint8_t threads, | 451 | uint8_t threads, |
| 447 | uint64_t data_size, | 452 | uint64_t data_size, |
| @@ -460,7 +465,7 @@ solve_h48( | |||
| 460 | int8_t d; | 465 | int8_t d; |
| 461 | dfsarg_solve_h48_t arg[THREADS]; | 466 | dfsarg_solve_h48_t arg[THREADS]; |
| 462 | solve_h48_task_t tasks[H48_STARTING_CUBES]; | 467 | solve_h48_task_t tasks[H48_STARTING_CUBES]; |
| 463 | dfsarg_solve_h48_maketasks_t maketasks_arg; | 468 | dfsarg_solve_h48_maketasks_t mtarg; |
| 464 | long double fallback_rate, lookups_per_node; | 469 | long double fallback_rate, lookups_per_node; |
| 465 | uint64_t offset; | 470 | uint64_t offset; |
| 466 | uint64_t nodes_visited, table_lookups, table_fallbacks; | 471 | uint64_t nodes_visited, table_lookups, table_fallbacks; |
| @@ -508,7 +513,6 @@ solve_h48( | |||
| 508 | fallback2 = h48data + offset; | 513 | fallback2 = h48data + offset; |
| 509 | 514 | ||
| 510 | settings = (solution_settings_t) { | 515 | settings = (solution_settings_t) { |
| 511 | .tmask = symmetry_mask(oc.cube), | ||
| 512 | .unniss = true, | 516 | .unniss = true, |
| 513 | .maxmoves = maxmoves, | 517 | .maxmoves = maxmoves, |
| 514 | .maxsolutions = maxsolutions, | 518 | .maxsolutions = maxsolutions, |
| @@ -543,14 +547,14 @@ solve_h48( | |||
| 543 | 547 | ||
| 544 | wrapthread_mutex_init(&solutions_mutex, NULL); | 548 | wrapthread_mutex_init(&solutions_mutex, NULL); |
| 545 | 549 | ||
| 546 | maketasks_arg = (dfsarg_solve_h48_maketasks_t) { | 550 | mtarg = (dfsarg_solve_h48_maketasks_t) { |
| 547 | .cube = oc.cube, | 551 | .cube = oc.cube, |
| 548 | .nmoves = 0, | 552 | .nmoves = 0, |
| 549 | .minmoves = minmoves, | 553 | .minmoves = minmoves, |
| 550 | .maxmoves = maxmoves, | 554 | .maxmoves = maxmoves, |
| 551 | }; | 555 | }; |
| 552 | ntasks = 0; | 556 | ntasks = 0; |
| 553 | solve_h48_maketasks(&arg[0], &maketasks_arg, tasks, &ntasks); | 557 | solve_h48_maketasks(&arg[0], &mtarg, tasks, &ntasks); |
| 554 | if (ntasks < 0) | 558 | if (ntasks < 0) |
| 555 | goto solve_h48_error_solutions_buffer; | 559 | goto solve_h48_error_solutions_buffer; |
| 556 | if (solutions_done(&sollist, &settings, | 560 | if (solutions_done(&sollist, &settings, |
