diff options
| author | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-12-07 12:20:51 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano.tronto@gmail.com> | 2021-12-07 12:20:51 +0100 |
| commit | b6fd508253bce9225dd24b6538adb5093892c4f8 (patch) | |
| tree | 75f58f26fca63f0bbda0a351a2cb8f514194a35b /src/solve.c | |
| parent | e528411b1a1be45e1bef0f525fd0f411c9689b11 (diff) | |
| download | nissy-b6fd508253bce9225dd24b6538adb5093892c4f8.tar.gz nissy-b6fd508253bce9225dd24b6538adb5093892c4f8.zip | |
Little performance improvement in optimal solver - more to come!
Diffstat (limited to 'src/solve.c')
| -rw-r--r-- | src/solve.c | 125 |
1 files changed, 73 insertions, 52 deletions
diff --git a/src/solve.c b/src/solve.c index a35a837..881edd6 100644 --- a/src/solve.c +++ b/src/solve.c | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | /* Local functions ***********************************************************/ | 3 | /* Local functions ***********************************************************/ |
| 4 | 4 | ||
| 5 | static bool allowed_next(Move move, DfsData *dd); | 5 | static bool allowed_next(Move move, DfsData *dd, uint64_t mm); |
| 6 | static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd); | 6 | static void dfs(Cube c, Step *s, SolveOptions *opts, DfsData *dd); |
| 7 | static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd); | 7 | static void dfs_branch(Cube c, Step *s, SolveOptions *os, DfsData *dd); |
| 8 | static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd); | 8 | static bool dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd); |
| @@ -14,8 +14,11 @@ static void multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, | |||
| 14 | /* Local functions ***********************************************************/ | 14 | /* Local functions ***********************************************************/ |
| 15 | 15 | ||
| 16 | static bool | 16 | static bool |
| 17 | allowed_next(Move move, DfsData *dd) | 17 | allowed_next(Move move, DfsData *dd, uint64_t mm) |
| 18 | { | 18 | { |
| 19 | if ((1 << move) & mm) | ||
| 20 | return false; | ||
| 21 | |||
| 19 | if (!possible_next(dd->last2, dd->last1, move)) | 22 | if (!possible_next(dd->last2, dd->last1, move)) |
| 20 | return false; | 23 | return false; |
| 21 | 24 | ||
| @@ -45,23 +48,21 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 45 | { | 48 | { |
| 46 | bool b = false; | 49 | bool b = false; |
| 47 | int i; | 50 | int i; |
| 51 | uint64_t mm; | ||
| 48 | Move m, l1, l2; | 52 | Move m, l1, l2; |
| 53 | LocalInfo li; | ||
| 49 | 54 | ||
| 50 | l1 = dd->last1; | 55 | l1 = dd->last1; |
| 51 | l2 = dd->last2; | 56 | l2 = dd->last2; |
| 57 | li = *(dd->ed->li); | ||
| 58 | mm = dd->ed->movebitmask; | ||
| 52 | 59 | ||
| 53 | for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) { | 60 | for (i = 0; dd->sorted_moves[i] != NULLMOVE; i++) { |
| 54 | /* | ||
| 55 | pthread_mutex_lock(dd->sols_mutex); | ||
| 56 | b = dd->sols->len >= opts->max_solutions; | ||
| 57 | pthread_mutex_unlock(dd->sols_mutex); | ||
| 58 | */ | ||
| 59 | |||
| 60 | if (b) | 61 | if (b) |
| 61 | break; | 62 | break; |
| 62 | 63 | ||
| 63 | m = dd->sorted_moves[i]; | 64 | m = dd->sorted_moves[i]; |
| 64 | if (allowed_next(m, dd)) { | 65 | if (allowed_next(m, dd, mm)) { |
| 65 | dd->last2 = dd->last1; | 66 | dd->last2 = dd->last1; |
| 66 | dd->last1 = m; | 67 | dd->last1 = m; |
| 67 | append_move(dd->current_alg, m, dd->niss); | 68 | append_move(dd->current_alg, m, dd->niss); |
| @@ -69,8 +70,9 @@ dfs_branch(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 69 | dfs(apply_move(m, c), s, opts, dd); | 70 | dfs(apply_move(m, c), s, opts, dd); |
| 70 | 71 | ||
| 71 | dd->current_alg->len--; | 72 | dd->current_alg->len--; |
| 72 | dd->last2 = l2; | 73 | dd->last2 = l2; |
| 73 | dd->last1 = l1; | 74 | dd->last1 = l1; |
| 75 | *(dd->ed->li) = li; | ||
| 74 | } | 76 | } |
| 75 | } | 77 | } |
| 76 | } | 78 | } |
| @@ -99,13 +101,17 @@ dfs_check_solved(Step *s, SolveOptions *opts, DfsData *dd) | |||
| 99 | static void | 101 | static void |
| 100 | dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | 102 | dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) |
| 101 | { | 103 | { |
| 102 | Move l1 = dd->last1, l2 = dd->last2; | 104 | Move l1, l2; |
| 103 | CubeTarget ct; | 105 | EstimateData *ed; |
| 104 | 106 | ||
| 105 | ct.cube = apply_move(inverse_move(l1), (Cube){0}); | 107 | l1 = dd->last1; |
| 106 | ct.target = 1; | 108 | l2 = dd->last2; |
| 109 | |||
| 110 | ed = malloc(sizeof(EstimateData)); | ||
| 111 | ed->cube = apply_move(inverse_move(l1), (Cube){0}); | ||
| 112 | ed->target = 1; | ||
| 107 | 113 | ||
| 108 | if (dd->current_alg->len == 0 || s->estimate(ct)) { | 114 | if (dd->current_alg->len == 0 || s->estimate(ed)) { |
| 109 | dd->niss = true; | 115 | dd->niss = true; |
| 110 | dd->last1 = NULLMOVE; | 116 | dd->last1 = NULLMOVE; |
| 111 | dd->last2 = NULLMOVE; | 117 | dd->last2 = NULLMOVE; |
| @@ -116,28 +122,31 @@ dfs_niss(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | |||
| 116 | dd->last2 = l2; | 122 | dd->last2 = l2; |
| 117 | dd->niss = false; | 123 | dd->niss = false; |
| 118 | } | 124 | } |
| 125 | |||
| 126 | free(ed); | ||
| 119 | } | 127 | } |
| 120 | 128 | ||
| 121 | static bool | 129 | static bool |
| 122 | dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) | 130 | dfs_stop(Cube c, Step *s, SolveOptions *opts, DfsData *dd) |
| 123 | { | 131 | { |
| 124 | bool b = false; | 132 | bool b; |
| 125 | 133 | ||
| 126 | CubeTarget ct = { | 134 | dd->ed->cube = c; |
| 127 | .cube = c, | 135 | dd->ed->target = dd->d - dd->current_alg->len; |
| 128 | .target = dd->d - dd->current_alg->len | 136 | dd->ed->lastmove = dd->last1; |
| 129 | }; | 137 | dd->ed->movebitmask = 0; |
| 130 | 138 | ||
| 131 | dd->lb = s->estimate(ct); | 139 | dd->lb = s->estimate(dd->ed); |
| 132 | if (opts->can_niss && !dd->niss) | 140 | if (opts->can_niss && !dd->niss) |
| 133 | dd->lb = MIN(1, dd->lb); | 141 | dd->lb = MIN(1, dd->lb); |
| 134 | 142 | ||
| 135 | if (dd->current_alg->len + dd->lb > dd->d) | 143 | if (dd->current_alg->len + dd->lb > dd->d) { |
| 136 | return true; | 144 | b = true; |
| 137 | 145 | } else { | |
| 138 | pthread_mutex_lock(dd->sols_mutex); | 146 | pthread_mutex_lock(dd->sols_mutex); |
| 139 | b = dd->sols->len >= opts->max_solutions; | 147 | b = dd->sols->len >= opts->max_solutions; |
| 140 | pthread_mutex_unlock(dd->sols_mutex); | 148 | pthread_mutex_unlock(dd->sols_mutex); |
| 149 | } | ||
| 141 | 150 | ||
| 142 | return b; | 151 | return b; |
| 143 | } | 152 | } |
| @@ -170,30 +179,28 @@ instance_thread(void *arg) | |||
| 170 | apply_move(node->alg->move[0], inverse_cube(td->cube)) : | 179 | apply_move(node->alg->move[0], inverse_cube(td->cube)) : |
| 171 | apply_move(node->alg->move[0], td->cube); | 180 | apply_move(node->alg->move[0], td->cube); |
| 172 | 181 | ||
| 173 | dd.d = td->depth; | 182 | dd.d = td->depth; |
| 174 | dd.m = 1; | 183 | dd.m = 1; |
| 175 | dd.niss = node->alg->inv[0]; | 184 | dd.niss = node->alg->inv[0]; |
| 176 | dd.lb = -1; | 185 | dd.lb = -1; |
| 177 | dd.last1 = node->alg->move[0]; | 186 | dd.last1 = node->alg->move[0]; |
| 178 | dd.last2 = NULLMOVE; | 187 | dd.last2 = NULLMOVE; |
| 179 | dd.sols = td->sols; | 188 | dd.sols = td->sols; |
| 180 | dd.sols_mutex = td->sols_mutex; | 189 | dd.sols_mutex = td->sols_mutex; |
| 181 | dd.current_alg = new_alg(""); | 190 | dd.current_alg = new_alg(""); |
| 182 | append_move(dd.current_alg, node->alg->move[0], | 191 | append_move(dd.current_alg, node->alg->move[0], |
| 183 | node->alg->inv[0]); | 192 | node->alg->inv[0]); |
| 184 | dd.sorted_moves = td->sorted_moves; | 193 | dd.sorted_moves = td->sorted_moves; |
| 185 | dd.move_position = td->move_position; | 194 | dd.move_position = td->move_position; |
| 186 | 195 | dd.ed = malloc(sizeof(EstimateData)); | |
| 187 | /* | 196 | dd.ed->movebitmask = 0; |
| 188 | pthread_mutex_lock(td->sols_mutex); | 197 | dd.ed->li = new_localinfo(); |
| 189 | printf("Starting thread %d with move: ", td->thid); | ||
| 190 | print_alg(dd.current_alg, false); | ||
| 191 | pthread_mutex_unlock(td->sols_mutex); | ||
| 192 | */ | ||
| 193 | 198 | ||
| 194 | dfs(c, td->step, td->opts, &dd); | 199 | dfs(c, td->step, td->opts, &dd); |
| 195 | 200 | ||
| 196 | free_alg(dd.current_alg); | 201 | free_alg(dd.current_alg); |
| 202 | free_localinfo(dd.ed->li); | ||
| 203 | free(dd.ed); | ||
| 197 | } | 204 | } |
| 198 | 205 | ||
| 199 | return NULL; | 206 | return NULL; |
| @@ -223,6 +230,7 @@ multidfs(Cube c, Step *s, SolveOptions *opts, AlgList *sols, int d) | |||
| 223 | 230 | ||
| 224 | moveset_to_list(s->moveset, sorted_moves); | 231 | moveset_to_list(s->moveset, sorted_moves); |
| 225 | movelist_to_position(sorted_moves, move_position); | 232 | movelist_to_position(sorted_moves, move_position); |
| 233 | |||
| 226 | for (i = 0; sorted_moves[i] != NULLMOVE; i++) { | 234 | for (i = 0; sorted_moves[i] != NULLMOVE; i++) { |
| 227 | alg = new_alg(""); | 235 | alg = new_alg(""); |
| 228 | append_move(alg, sorted_moves[i], false); | 236 | append_move(alg, sorted_moves[i], false); |
| @@ -268,9 +276,11 @@ AlgList * | |||
| 268 | solve(Cube cube, Step *step, SolveOptions *opts) | 276 | solve(Cube cube, Step *step, SolveOptions *opts) |
| 269 | { | 277 | { |
| 270 | int d; | 278 | int d; |
| 271 | AlgList *sols = new_alglist(); | 279 | AlgList *sols; |
| 272 | AlgListNode *node; | 280 | AlgListNode *node; |
| 273 | Cube c; | 281 | Cube c; |
| 282 | EstimateData *ed; | ||
| 283 | bool b; | ||
| 274 | 284 | ||
| 275 | prepare_step(step); | 285 | prepare_step(step); |
| 276 | 286 | ||
| @@ -278,19 +288,30 @@ solve(Cube cube, Step *step, SolveOptions *opts) | |||
| 278 | step->pre_trans = step->detect(cube); | 288 | step->pre_trans = step->detect(cube); |
| 279 | c = apply_trans(step->pre_trans, cube); | 289 | c = apply_trans(step->pre_trans, cube); |
| 280 | 290 | ||
| 291 | sols = new_alglist(); | ||
| 292 | |||
| 281 | if (step->ready != NULL && !step->ready(c)) { | 293 | if (step->ready != NULL && !step->ready(c)) { |
| 282 | fprintf(stderr, "Cube not ready for solving step: "); | 294 | fprintf(stderr, "Cube not ready for solving step: "); |
| 283 | fprintf(stderr, "%s\n", step->ready_msg); | 295 | fprintf(stderr, "%s\n", step->ready_msg); |
| 284 | return sols; | 296 | return sols; |
| 285 | } | 297 | } |
| 286 | 298 | ||
| 287 | if (step->estimate((CubeTarget){.cube = c, .target = 0}) == 0 && | 299 | if (opts->min_moves == 0) { |
| 288 | opts->min_moves == 0) { | 300 | ed = malloc(sizeof(EstimateData)); |
| 289 | append_alg(sols, new_alg("")); | 301 | ed->cube = cube; |
| 290 | return sols; | 302 | ed->target = 0; |
| 303 | ed->li = new_localinfo(); | ||
| 304 | b = step->estimate(ed) == 0; | ||
| 305 | free_localinfo(ed->li); | ||
| 306 | free(ed); | ||
| 307 | |||
| 308 | if (b) { | ||
| 309 | append_alg(sols, new_alg("")); | ||
| 310 | return sols; | ||
| 311 | } | ||
| 291 | } | 312 | } |
| 292 | 313 | ||
| 293 | for (d = MAX(1, opts->min_moves); | 314 | for (d = opts->min_moves; |
| 294 | d <= opts->max_moves && | 315 | d <= opts->max_moves && |
| 295 | !(sols->len && opts->optimal_only) && | 316 | !(sols->len && opts->optimal_only) && |
| 296 | sols->len < opts->max_solutions; | 317 | sols->len < opts->max_solutions; |
