aboutsummaryrefslogtreecommitdiff
path: root/src/solvers/h48
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-11-25 18:03:50 +0100
committerSebastiano Tronto <sebastiano@tronto.net>2025-11-25 18:03:50 +0100
commit4d0b1a53f04f1c5bc95de20fb92b2bd9cf16a895 (patch)
tree5294d9b3655031535085a5163c2c5b5cbe7413b1 /src/solvers/h48
parent3ca4814562f6c756e9a110dab7d54cda30267fb1 (diff)
parent147b0c3c4615c32478a4923242909b8ae5a30d03 (diff)
downloadnissy-core-4d0b1a53f04f1c5bc95de20fb92b2bd9cf16a895.tar.gz
nissy-core-4d0b1a53f04f1c5bc95de20fb92b2bd9cf16a895.zip
Merge branch 'master' of tronto.net:nissy-core
Diffstat (limited to 'src/solvers/h48')
-rw-r--r--src/solvers/h48/solve.h78
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
18typedef struct { 19typedef 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
60STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned, 63STATIC long long solve_h48_dispatch(oriented_cube_t, const char *, unsigned,
@@ -69,7 +72,7 @@ STATIC void *solve_h48_runthread(void *);
69STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]); 72STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t [static 1]);
70STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t); 73STATIC void solve_h48_log_solutions(solution_list_t [static 1], size_t);
71STATIC int solve_h48_compare_tasks(const void *, const void *); 74STATIC int solve_h48_compare_tasks(const void *, const void *);
72STATIC int64_t solve_h48(oriented_cube_t, uint8_t, uint8_t, uint8_t, uint8_t, 75STATIC 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:
341STATIC int64_t 345STATIC int64_t
342solve_h48_maketasks( 346solve_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,

Generated with cgit - Back to sebastiano.tronto.net