diff options
Diffstat (limited to '')
| -rw-r--r-- | TODO.md | 4 | ||||
| -rw-r--r-- | src/pruning.c | 176 |
2 files changed, 0 insertions, 180 deletions
| @@ -58,10 +58,6 @@ and just use previous values for all 3 axes. | |||
| 58 | 58 | ||
| 59 | ## Coordinates, symmetries, pruning tables | 59 | ## Coordinates, symmetries, pruning tables |
| 60 | * use multiple threads to search for solutions in parallel | 60 | * use multiple threads to search for solutions in parallel |
| 61 | * Faster pruning table generation: keep track of which positions are "nasty" | ||
| 62 | (i.e. self-symmetric with respect to the base symmetry coordinate but not | ||
| 63 | self-symmetric overall) by adding a function to struct coord and some datafield | ||
| 64 | to struct symdata. | ||
| 65 | * Faster pruning table generation: multithreading (divide table into large | 61 | * Faster pruning table generation: multithreading (divide table into large |
| 66 | sections and use one mutex for each section to avoid too much locking) | 62 | sections and use one mutex for each section to avoid too much locking) |
| 67 | * Cleanup symcoord.c: some coordinates and symdata are never actually used; | 63 | * Cleanup symcoord.c: some coordinates and symdata are never actually used; |
diff --git a/src/pruning.c b/src/pruning.c index 6ea77e3..50299f0 100644 --- a/src/pruning.c +++ b/src/pruning.c | |||
| @@ -1,18 +1,5 @@ | |||
| 1 | #include "pruning.h" | 1 | #include "pruning.h" |
| 2 | 2 | ||
| 3 | /* | ||
| 4 | * The commented functions are a way to generate a pruning table | ||
| 5 | * without using anti-indexes. It does not matter too much because | ||
| 6 | * we still need anti-indexes in gensym. | ||
| 7 | */ | ||
| 8 | /* | ||
| 9 | static bool dfs_get_visited(PruneData *pd, DfsData *dd, Cube c); | ||
| 10 | static bool dfs_get_visited_index(DfsData *dd, uint64_t ind); | ||
| 11 | static void dfs_set_visited(PruneData *pd, DfsData *dd, Cube c, bool b); | ||
| 12 | static void dfs_set_visited_index(DfsData *dd, uint64_t ind, bool b); | ||
| 13 | static void genptable_dfs(Cube c, PruneData *pd, DfsData *dd); | ||
| 14 | */ | ||
| 15 | |||
| 16 | static void genptable_bfs(PruneData *pd, int d, Move *ms); | 3 | static void genptable_bfs(PruneData *pd, int d, Move *ms); |
| 17 | static void genptable_branch(PruneData *pd,uint64_t ind,int d,Move *ms); | 4 | static void genptable_branch(PruneData *pd,uint64_t ind,int d,Move *ms); |
| 18 | static void ptable_update(PruneData *pd, Cube cube, int m); | 5 | static void ptable_update(PruneData *pd, Cube cube, int m); |
| @@ -172,53 +159,6 @@ genptable_bfs(PruneData *pd, int d, Move *ms) | |||
| 172 | static void | 159 | static void |
| 173 | genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms) | 160 | genptable_branch(PruneData *pd, uint64_t ind, int d, Move *ms) |
| 174 | { | 161 | { |
| 175 | /* | ||
| 176 | * Here we deal with the following problem: | ||
| 177 | * The set of positions reached by applying each move to | ||
| 178 | * a certain position X could depend on the representative | ||
| 179 | * used for X in its symmetry class. | ||
| 180 | * This is a terribly inefficient way to deal with this. | ||
| 181 | * TODO: make it more efficient. | ||
| 182 | */ | ||
| 183 | /* | ||
| 184 | * IDEA (with the example of khuge in mind): | ||
| 185 | * The problem only happens when two position that are actually | ||
| 186 | * in the same class are considered different. This can happen | ||
| 187 | * because only CO is used to determine which transformation | ||
| 188 | * to apply to get a representative for the class. So if the | ||
| 189 | * corners are in a self-symmetric position more than one | ||
| 190 | * transformation to the representative is possible, only one | ||
| 191 | * (essentially at random) is picked, but this is not necessarily | ||
| 192 | * the correct one if the edges are not in a self-symmetric | ||
| 193 | * position. | ||
| 194 | * SOLUTION: Keep in mind which corner positions are | ||
| 195 | * self-symmetric (add a field to symdata). Add a function | ||
| 196 | * to coord that tells if a position has this problem, or | ||
| 197 | * even the list of transformations that need to be tried. | ||
| 198 | * The second option is a bit more complicated but more | ||
| 199 | * efficient and allows for removing the ntrans and trans | ||
| 200 | * field from struct coordinate. | ||
| 201 | */ | ||
| 202 | /* Work in progress, first attempt */ | ||
| 203 | |||
| 204 | /* | ||
| 205 | int i, j; | ||
| 206 | Cube ci, cc, c; | ||
| 207 | |||
| 208 | |||
| 209 | ci = pd->coord->cube(ind); | ||
| 210 | |||
| 211 | for (i = 0; i < pd->coord->ntrans; i++) { | ||
| 212 | c = i == 0 ? ci : | ||
| 213 | apply_trans(pd->coord->trans[i], ci); | ||
| 214 | for (j = 0; ms[j] != NULLMOVE; j++) { | ||
| 215 | cc = apply_move(ms[j], c); | ||
| 216 | if (ptableval(pd, cc) > d+1) | ||
| 217 | ptable_update(pd, cc, d+1); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | */ | ||
| 221 | |||
| 222 | int i; | 162 | int i; |
| 223 | Cube c, cc; | 163 | Cube c, cc; |
| 224 | 164 | ||
| @@ -339,119 +279,3 @@ write_ptable_file(PruneData *pd) | |||
| 339 | return written == ptablesize(pd); | 279 | return written == ptablesize(pd); |
| 340 | } | 280 | } |
| 341 | 281 | ||
| 342 | /* | ||
| 343 | I'll put here all the leftover code from the genptable-dfs attempt. | ||
| 344 | Might be useful in the future. | ||
| 345 | */ | ||
| 346 | |||
| 347 | /* | ||
| 348 | void | ||
| 349 | genptable(PruneData *pd) | ||
| 350 | { | ||
| 351 | Move *ms; | ||
| 352 | uint64_t j, oldn; | ||
| 353 | DfsData dd; | ||
| 354 | |||
| 355 | if (pd->generated) | ||
| 356 | return; | ||
| 357 | |||
| 358 | pd->ptable = malloc(ptablesize(pd) * sizeof(uint8_t)); | ||
| 359 | |||
| 360 | if (read_ptable_file(pd)) { | ||
| 361 | pd->generated = true; | ||
| 362 | return; | ||
| 363 | } | ||
| 364 | pd->generated = true; | ||
| 365 | |||
| 366 | fprintf(stderr, "Cannot load %s, generating it\n", pd->filename); | ||
| 367 | |||
| 368 | ms = malloc(NMOVES * sizeof(Move)); | ||
| 369 | moveset_to_list(pd->moveset, ms); | ||
| 370 | |||
| 371 | for (j = 0; j < pd->coord->max; j++) | ||
| 372 | ptable_update_index(pd, j, 15); | ||
| 373 | |||
| 374 | dd = (DfsData) { .m = 0 }; | ||
| 375 | dd.visited = malloc((ptablesize(pd)/4 + 1) * sizeof(uint8_t)); | ||
| 376 | dd.sorted_moves = malloc(NMOVES * sizeof(Move)); | ||
| 377 | moveset_to_list(pd->moveset, dd.sorted_moves); | ||
| 378 | oldn = 0; | ||
| 379 | pd->n = 0; | ||
| 380 | |||
| 381 | for (dd.d = 0; dd.d < 15 && pd->n < pd->coord->max; dd.d++) { | ||
| 382 | for (j = 0; j < pd->coord->max; j++) | ||
| 383 | dfs_set_visited_index(&dd, j, false); | ||
| 384 | genptable_dfs((Cube){0}, pd, &dd); | ||
| 385 | fprintf(stderr, "Depth %d done, generated %" | ||
| 386 | PRIu64 "\t(%" PRIu64 "/%" PRIu64 ")\n", | ||
| 387 | dd.d+1, pd->n - oldn, pd->n, pd->coord->max); | ||
| 388 | oldn = pd->n; | ||
| 389 | } | ||
| 390 | |||
| 391 | if (!write_ptable_file(pd)) | ||
| 392 | fprintf(stderr, "Error writing ptable file\n"); | ||
| 393 | |||
| 394 | free(ms); | ||
| 395 | free(dd.visited); | ||
| 396 | free(dd.sorted_moves); | ||
| 397 | } | ||
| 398 | |||
| 399 | static void | ||
| 400 | genptable_dfs(Cube c, PruneData *pd, DfsData *dd) | ||
| 401 | { | ||
| 402 | int i, j, pv; | ||
| 403 | Move mm; | ||
| 404 | Cube cc; | ||
| 405 | |||
| 406 | pv = ptableval(pd, c); | ||
| 407 | |||
| 408 | if (pv < dd->m || dd->m > dd->d) | ||
| 409 | return; | ||
| 410 | |||
| 411 | if (dfs_get_visited(pd, dd, c)) | ||
| 412 | return; | ||
| 413 | dfs_set_visited(pd, dd, c, true); | ||
| 414 | |||
| 415 | if (pv != dd->m) | ||
| 416 | ptable_update(pd, c, dd->m); | ||
| 417 | |||
| 418 | for (i = 0; i < pd->coord->ntrans; i++) { | ||
| 419 | cc = i == 0 ? c : | ||
| 420 | apply_trans(pd->coord->trans[i], c); | ||
| 421 | for (j = 0; dd->sorted_moves[j] != NULLMOVE; j++) { | ||
| 422 | mm = dd->sorted_moves[j]; | ||
| 423 | dd->m++; | ||
| 424 | genptable_dfs(apply_move(mm, cc), pd, dd); | ||
| 425 | dd->m--; | ||
| 426 | } | ||
| 427 | } | ||
| 428 | } | ||
| 429 | |||
| 430 | static bool | ||
| 431 | dfs_get_visited(PruneData *pd, DfsData *dd, Cube c) | ||
| 432 | { | ||
| 433 | return dfs_get_visited_index(dd, pd->coord->index(c)); | ||
| 434 | } | ||
| 435 | |||
| 436 | static bool | ||
| 437 | dfs_get_visited_index(DfsData *dd, uint64_t ind) | ||
| 438 | { | ||
| 439 | return dd->visited[ind/8] & ((uint8_t)1 << (ind % 8)); | ||
| 440 | } | ||
| 441 | |||
| 442 | static void | ||
| 443 | dfs_set_visited(PruneData *pd, DfsData *dd, Cube c, bool b) | ||
| 444 | { | ||
| 445 | dfs_set_visited_index(dd, pd->coord->index(c), b); | ||
| 446 | } | ||
| 447 | |||
| 448 | static void | ||
| 449 | dfs_set_visited_index(DfsData *dd, uint64_t ind, bool b) | ||
| 450 | { | ||
| 451 | if (b) | ||
| 452 | dd->visited[ind/8] |= ((uint8_t)1 << (ind % 8)); | ||
| 453 | else | ||
| 454 | dd->visited[ind/8] &= ~((uint8_t)1 << (ind % 8)); | ||
| 455 | } | ||
| 456 | |||
| 457 | */ | ||
