aboutsummaryrefslogtreecommitdiff
path: root/src/solve.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/solve.c')
-rw-r--r--src/solve.c133
1 files changed, 76 insertions, 57 deletions
diff --git a/src/solve.c b/src/solve.c
index 911d208..df15cca 100644
--- a/src/solve.c
+++ b/src/solve.c
@@ -4,7 +4,7 @@
4 4
5/* Local functions ***********************************************************/ 5/* Local functions ***********************************************************/
6 6
7static bool allowed_next(Move move, StepAlt *sa, Move l0, Move l1); 7static bool allowed_next(Move move, Step *s, Move l0, Move l1);
8static bool cancel_niss(DfsArg *arg); 8static bool cancel_niss(DfsArg *arg);
9static void copy_dfsarg(DfsArg *src, DfsArg *dst); 9static void copy_dfsarg(DfsArg *src, DfsArg *dst);
10static void dfs(DfsArg *arg); 10static void dfs(DfsArg *arg);
@@ -19,13 +19,13 @@ static bool solvestop(int d, int op, SolveOptions *opts, AlgList *sols);
19/* Local functions ***********************************************************/ 19/* Local functions ***********************************************************/
20 20
21static bool 21static bool
22allowed_next(Move m, StepAlt *sa, Move l0, Move l1) 22allowed_next(Move m, Step *s, Move l0, Move l1)
23{ 23{
24 bool allowed, order; 24 bool allowed, order;
25 uint64_t mbit; 25 uint64_t mbit;
26 26
27 mbit = ((uint64_t)1) << m; 27 mbit = ((uint64_t)1) << m;
28 allowed = mbit & sa->moveset->mask[l1][l0]; 28 allowed = mbit & s->moveset->mask[l1][l0];
29 order = !commute(l0, m) || l0 < m; 29 order = !commute(l0, m) || l0 < m;
30 30
31 return allowed && order; 31 return allowed && order;
@@ -41,7 +41,7 @@ cancel_niss(DfsArg *arg)
41 if (arg->lastinv[0] == NULLMOVE) 41 if (arg->lastinv[0] == NULLMOVE)
42 return false; 42 return false;
43 43
44 ms = arg->sa->moveset; 44 ms = arg->s->moveset;
45 i1 = inverse_move(arg->lastinv[0]); 45 i1 = inverse_move(arg->lastinv[0]);
46 i2 = inverse_move(arg->lastinv[1]); 46 i2 = inverse_move(arg->lastinv[1]);
47 47
@@ -63,7 +63,7 @@ copy_dfsarg(DfsArg *src, DfsArg *dst)
63 63
64 dst->cube = src->cube; 64 dst->cube = src->cube;
65 dst->t = src->t; 65 dst->t = src->t;
66 dst->sa = src->sa; 66 dst->s = src->s;
67 dst->opts = src->opts; 67 dst->opts = src->opts;
68 dst->d = src->d; 68 dst->d = src->d;
69 dst->bound = src->bound; /* In theory not needed */ 69 dst->bound = src->bound; /* In theory not needed */
@@ -77,10 +77,14 @@ copy_dfsarg(DfsArg *src, DfsArg *dst)
77 dst->lastinv[i] = src->lastinv[i]; 77 dst->lastinv[i] = src->lastinv[i];
78 } 78 }
79 79
80 for (i = 0; i < src->sa->n_coord; i++) { 80 for (i = 0; i < src->s->n_coord; i++) {
81 dst->ind[i].val = src->ind[i].val; 81 dst->ind[i].val = src->ind[i].val;
82 dst->ind[i].t = src->ind[i].t; 82 dst->ind[i].t = src->ind[i].t;
83 } 83 }
84
85/*
86 src->s->copy_extra(src, dst);
87*/
84} 88}
85 89
86static void 90static void
@@ -99,9 +103,9 @@ dfs(DfsArg *arg)
99 return; 103 return;
100 } 104 }
101 105
102 for (i = 0; arg->sa->moveset->sorted_moves[i] != NULLMOVE; i++) { 106 for (i = 0; arg->s->moveset->sorted_moves[i] != NULLMOVE; i++) {
103 m = arg->sa->moveset->sorted_moves[i]; 107 m = arg->s->moveset->sorted_moves[i];
104 if (allowed_next(m, arg->sa, arg->last[0], arg->last[1])) { 108 if (allowed_next(m, arg->s, arg->last[0], arg->last[1])) {
105 copy_dfsarg(arg, &newarg); 109 copy_dfsarg(arg, &newarg);
106 newarg.last[1] = arg->last[0]; 110 newarg.last[1] = arg->last[0];
107 newarg.last[0] = m; 111 newarg.last[0] = m;
@@ -120,9 +124,9 @@ dfs_add_sol(DfsArg *arg)
120{ 124{
121 bool valid, accepted, nisscanc; 125 bool valid, accepted, nisscanc;
122 126
123 valid = arg->sa->is_valid==NULL || arg->sa->is_valid(arg->current_alg); 127 valid = arg->s->is_valid==NULL || arg->s->is_valid(arg->current_alg);
124 accepted = valid || arg->opts->all; 128 accepted = valid || arg->opts->all;
125 nisscanc = arg->sa->final && cancel_niss(arg); 129 nisscanc = arg->s->final && cancel_niss(arg);
126 130
127 if (accepted && !nisscanc) { 131 if (accepted && !nisscanc) {
128 pthread_mutex_lock(arg->sols_mutex); 132 pthread_mutex_lock(arg->sols_mutex);
@@ -159,7 +163,7 @@ dfs_niss(DfsArg *arg)
159 compose(c, newarg.cube); 163 compose(c, newarg.cube);
160 164
161 /* New indexes */ 165 /* New indexes */
162 compute_ind(newarg.sa, newarg.cube, newarg.ind); 166 compute_ind(newarg.s, newarg.cube, newarg.ind);
163 167
164 swapmove(&(newarg.last[0]), &(newarg.lastinv[0])); 168 swapmove(&(newarg.last[0]), &(newarg.lastinv[0]));
165 swapmove(&(newarg.last[1]), &(newarg.lastinv[1])); 169 swapmove(&(newarg.last[1]), &(newarg.lastinv[1]));
@@ -175,36 +179,35 @@ dfs_niss(DfsArg *arg)
175static bool 179static bool
176dfs_move_checkstop(DfsArg *arg) 180dfs_move_checkstop(DfsArg *arg)
177{ 181{
178 bool b; 182 int i, goal, nsols;
179 int i, goal;
180 Move mm; 183 Move mm;
181 Trans tt = uf; /* Avoid uninitialized warning */ 184 Trans tt = uf; /* Avoid uninitialized warning */
182 185
183 /* Moving */ 186 /* Moving and computing bound */
184 if (arg->last[0] != NULLMOVE) { 187 arg->bound = 0;
185 for (i = 0; i < arg->sa->n_coord; i++) { 188 goal = arg->d - arg->current_alg->len;
189 for (i = 0; i < arg->s->n_coord; i++) {
190 if (arg->last[0] != NULLMOVE) {
186 mm = transform_move(arg->ind[i].t, arg->last[0]); 191 mm = transform_move(arg->ind[i].t, arg->last[0]);
187 arg->ind[i].val = move_coord(arg->sa->coord[i], 192 arg->ind[i].val = move_coord(arg->s->coord[i],
188 mm, arg->ind[i].val, &tt); 193 mm, arg->ind[i].val, &tt);
189 arg->ind[i].t = transform_trans(tt, arg->ind[i].t); 194 arg->ind[i].t = transform_trans(tt, arg->ind[i].t);
190 } 195 }
191 }
192 196
193 /* Computing bound for coordinates */ 197 arg->bound =
194 goal = arg->d - arg->current_alg->len; 198 MAX(arg->bound, ptableval(arg->s->pd[i], arg->ind[i].val));
195 arg->bound = estimate_stepalt(arg->sa, arg->ind, goal); 199 if (arg->opts->can_niss && !arg->niss)
196 if (arg->opts->can_niss && !arg->niss) 200 arg->bound = MIN(1, arg->bound);
197 arg->bound = MIN(1, arg->bound);
198 201
199 if (arg->bound > goal) { 202 if (arg->bound > goal)
200 b = true; 203 return true;
201 } else {
202 pthread_mutex_lock(arg->sols_mutex);
203 b = arg->sols->len >= arg->opts->max_solutions;
204 pthread_mutex_unlock(arg->sols_mutex);
205 } 204 }
206 205
207 return b; 206 pthread_mutex_lock(arg->sols_mutex);
207 nsols = arg->sols->len;
208 pthread_mutex_unlock(arg->sols_mutex);
209
210 return nsols >= arg->opts->max_solutions;
208} 211}
209 212
210static void * 213static void *
@@ -240,7 +243,7 @@ instance_thread(void *arg)
240 invert_cube(&c); 243 invert_cube(&c);
241 244
242 copy_dfsarg(&td->arg, &darg); 245 copy_dfsarg(&td->arg, &darg);
243 compute_ind(td->arg.sa, &c, darg.ind); 246 compute_ind(td->arg.s, &c, darg.ind);
244 darg.cube = &c; 247 darg.cube = &c;
245 248
246 darg.niss = inv; 249 darg.niss = inv;
@@ -279,11 +282,11 @@ multidfs(DfsArg *arg)
279 pthread_mutex_init(start_mutex, NULL); 282 pthread_mutex_init(start_mutex, NULL);
280 pthread_mutex_init(sols_mutex, NULL); 283 pthread_mutex_init(sols_mutex, NULL);
281 284
282 for (i = 0; arg->sa->moveset->sorted_moves[i] != NULLMOVE; i++) { 285 for (i = 0; arg->s->moveset->sorted_moves[i] != NULLMOVE; i++) {
283 alg = new_alg(""); 286 alg = new_alg("");
284 append_move(alg, arg->sa->moveset->sorted_moves[i], false); 287 append_move(alg, arg->s->moveset->sorted_moves[i], false);
285 append_alg(start, alg); 288 append_alg(start, alg);
286 if (arg->opts->can_niss && !arg->sa->final) { 289 if (arg->opts->can_niss && !arg->s->final) {
287 alg->inv[0] = true; 290 alg->inv[0] = true;
288 append_alg(start, alg); 291 append_alg(start, alg);
289 } 292 }
@@ -318,15 +321,25 @@ multidfs(DfsArg *arg)
318static bool 321static bool
319niss_makes_sense(DfsArg *arg) 322niss_makes_sense(DfsArg *arg)
320{ 323{
321 Cube testcube; 324 Move m, mm;
325 uint64_t u;
326 int i;
322 327
323 if (arg->sa->final || arg->niss || !arg->opts->can_niss) 328 if (arg->s->final || arg->niss || !arg->opts->can_niss)
324 return false; 329 return false;
325 330
326 make_solved(&testcube); 331 if (arg->last[0] == NULLMOVE)
327 apply_move(inverse_move(arg->last[0]), &testcube); 332 return true;
328 return arg->current_alg->len == 0 || 333
329 estimate_stepalt(arg->sa, arg->ind, 0) > 0; 334 m = inverse_move(arg->last[0]);
335 for (i = 0; i < arg->s->n_coord; i++) {
336 mm = transform_move(arg->ind[i].t, m);
337 u = move_coord(arg->s->coord[i], mm, 0, NULL);
338 if (ptableval(arg->s->pd[i], u) > 0)
339 return true;
340 }
341
342 return false;
330} 343}
331 344
332static bool 345static bool
@@ -344,38 +357,38 @@ solvestop(int d, int op, SolveOptions *opts, AlgList *sols)
344/* Public functions **********************************************************/ 357/* Public functions **********************************************************/
345 358
346AlgList * 359AlgList *
347solve(Cube *cube, Step *step, SolveOptions *opts) 360solve(Cube *cube, ChoiceStep *cs, SolveOptions *opts)
348{ 361{
349 int i, d, op; 362 int i, j, d, op, est;
350 bool ready[99], one_ready, zerosol; 363 bool ready[99], one_ready, zerosol;
351 Movable ind[99][10]; 364 Movable ind[99][10];
352 AlgList *s; 365 AlgList *s;
353 Cube *c[99]; 366 Cube *c[99];
354 DfsArg arg[99]; 367 DfsArg arg[99];
355 368
356 prepare_step(step, opts); 369 prepare_cs(cs, opts);
357 s = new_alglist(); 370 s = new_alglist();
358 371
359 for (i = 0, one_ready = false; step->alt[i] != NULL; i++) { 372 for (i = 0, one_ready = false; cs->step[i] != NULL; i++) {
360 c[i] = malloc(sizeof(Cube)); 373 c[i] = malloc(sizeof(Cube));
361 copy_cube(cube, c[i]); 374 copy_cube(cube, c[i]);
362 apply_trans(step->t[i], c[i]); 375 apply_trans(cs->t[i], c[i]);
363 376
364 arg[i].cube = c[i]; 377 arg[i].cube = c[i];
365 arg[i].t = step->t[i]; 378 arg[i].t = cs->t[i];
366 arg[i].sa = step->alt[i]; 379 arg[i].s = cs->step[i];
367 arg[i].opts = opts; 380 arg[i].opts = opts;
368 arg[i].sols = s; 381 arg[i].sols = s;
369 382
370 if ((ready[i] = step->alt[i]->ready(c[i]))) { 383 if ((ready[i] = cs->step[i]->ready(c[i]))) {
371 one_ready = true; 384 one_ready = true;
372 /* Only for local use for 0 moves solutions */ 385 /* Only for local use for 0 moves solutions */
373 compute_ind(step->alt[i], c[i], ind[i]); 386 compute_ind(cs->step[i], c[i], ind[i]);
374 } 387 }
375 } 388 }
376 if (!one_ready) { 389 if (!one_ready) {
377 fprintf(stderr, "Cube not ready for solving step: "); 390 fprintf(stderr, "Cube not ready for solving step: ");
378 fprintf(stderr, "%s\n", step->ready_msg); 391 fprintf(stderr, "%s\n", cs->ready_msg);
379 return s; 392 return s;
380 } 393 }
381 394
@@ -383,10 +396,16 @@ solve(Cube *cube, Step *step, SolveOptions *opts)
383 * alternatives, all longer solutions will be discarded, so we may 396 * alternatives, all longer solutions will be discarded, so we may
384 * just set its ready[] value to false. If the solution is accepted 397 * just set its ready[] value to false. If the solution is accepted
385 * we append it and start searching from d = 1. */ 398 * we append it and start searching from d = 1. */
386 for (i = 0, zerosol = false; step->alt[i] != NULL; i++) { 399 for (i = 0, zerosol = false; cs->step[i] != NULL; i++) {
387 if (ready[i] && estimate_stepalt(step->alt[i],ind[i],0) == 0) { 400 if (ready[i]) {
388 ready[i] = false; 401 est = 0;
389 zerosol = true; 402 for (j = 0; j < cs->step[i]->n_coord; j++)
403 est = MAX(est, ptableval(cs->step[i]->pd[j],
404 ind[i][j].val));
405 if (est == 0) {
406 ready[i] = false;
407 zerosol = true;
408 }
390 } 409 }
391 } 410 }
392 if (zerosol && opts->min_moves == 0) { 411 if (zerosol && opts->min_moves == 0) {
@@ -401,7 +420,7 @@ solve(Cube *cube, Step *step, SolveOptions *opts)
401 if (opts->verbose) 420 if (opts->verbose)
402 fprintf(stderr, "Searching depth %d\n", d); 421 fprintf(stderr, "Searching depth %d\n", d);
403 422
404 for (i=0; step->alt[i]!=NULL && !solvestop(d,op,opts,s); i++) { 423 for (i=0; cs->step[i]!=NULL && !solvestop(d,op,opts,s); i++) {
405 if (!ready[i]) 424 if (!ready[i])
406 continue; 425 continue;
407 426
@@ -413,7 +432,7 @@ solve(Cube *cube, Step *step, SolveOptions *opts)
413 } 432 }
414 } 433 }
415 434
416 for (i = 0; step->alt[i] != NULL; i++) 435 for (i = 0; cs->step[i] != NULL; i++)
417 free(c[i]); 436 free(c[i]);
418 437
419 return s; 438 return s;

Generated with cgit - Back to sebastiano.tronto.net