Changeset 238
- Timestamp:
- 03/06/07 23:08:07 (1 year ago)
- Files:
-
- 06/libkombilo-branches/hash_center/Makefile (modified) (1 diff)
- 06/libkombilo-branches/hash_center/cpptest.cpp (modified) (1 diff)
- 06/libkombilo-branches/hash_center/process.py (modified) (1 diff)
- 06/libkombilo-branches/hash_center/search.cpp (modified) (37 diffs)
- 06/libkombilo-branches/hash_center/search.h (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
06/libkombilo-branches/hash_center/Makefile
r210 r238 5 5 g++ -c cpptest.cpp 6 6 7 search.o: search.cpp 7 search.o: search.cpp search.h abstractboard.h sgfparser.h 8 8 g++ -c search.cpp 9 9 10 sgfparser.o: sgfparser.cpp 10 sgfparser.o: sgfparser.cpp sgfparser.h 11 11 g++ -c sgfparser.cpp 12 12 13 abstractboard.o: abstractboard.cpp 13 abstractboard.o: abstractboard.cpp abstractboard.h 14 14 g++ -c abstractboard.cpp 15 15 06/libkombilo-branches/hash_center/cpptest.cpp
r233 r238 19 19 // ----------------- set up processing options ----------------------------------- 20 20 ProcessOptions* p_op = new ProcessOptions; 21 p_op->algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_ CENTER;21 p_op->algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER | ALGO_HASH_CENTER; 22 22 23 23 // ----------------- create GameList instance ----------------------------------- 06/libkombilo-branches/hash_center/process.py
r233 r238 21 21 try: 22 22 pop = ProcessOptions() 23 pop.algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_ CENTER23 pop.algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER | ALGO_HASH_CENTER 24 24 # pop.rootNodeTags = 'PW,PB,RE,DT' 25 25 pop.sgfInDB = False 26 gl = GameList('t1.db', 'id', '', pop, 1000)26 gl = GameList('t1.db', 'id', '', pop, 80) 27 27 except DBError: 28 28 print 'Database error' 06/libkombilo-branches/hash_center/search.cpp
r233 r238 145 145 146 146 147 148 147 // ----------- class Pattern ----------------------------------------------- 148 149 char invertColor(char co) { 150 if (co == 'X') return 'O'; 151 if (co == 'x') return 'o'; 152 153 if (co == 'O') return 'X'; 154 if (co == 'o') return 'x'; 155 156 return co; 157 } 149 158 150 159 int Pattern::operator==(const Pattern& p) { … … 158 167 } 159 168 160 161 169 char Pattern::BW2XO(char c) { 162 170 if (c == 'B') return 'X'; … … 173 181 } 174 182 175 176 183 Pattern::Pattern() { 177 184 initialPos = 0; … … 184 191 contLabels = 0; 185 192 } 186 187 193 188 194 Pattern::Pattern(int type, int BOARDSIZE, int sX, int sY, char* iPos, char* CONTLABELS) { … … 238 244 } 239 245 240 Pattern::Pattern(int type, int BOARDSIZE, int sX, int sY, 241 char* iPos, vector<MoveNC> CONTLIST, char* CONTLABELS) { 246 Pattern::Pattern(int type, int BOARDSIZE, int sX, int sY, char* iPos, vector<MoveNC> CONTLIST, char* CONTLABELS) { 242 247 flip = 0; 243 248 colorSwitch = 0; … … 293 298 } 294 299 295 Pattern::Pattern(int le, int ri, int to, int bo, int BOARDSIZE, int sX, int sY, 296 char* iPos, const vector<MoveNC>& CONTLIST, char* CONTLABELS) throw(PatternError) { 300 Pattern::Pattern(int le, int ri, int to, int bo, int BOARDSIZE, int sX, int sY, char* iPos, const vector<MoveNC>& CONTLIST, char* CONTLABELS) throw(PatternError) { 297 301 // check whether anchor rectangle is valid 298 302 if (le < 0 || ri+sX > BOARDSIZE || to < 0 || bo+sY > BOARDSIZE || ri < le || bo < to) throw PatternError(); … … 383 387 } 384 388 385 386 389 Pattern& Pattern::copy(const Pattern& p) { 387 390 if (&p != this) { … … 413 416 } 414 417 418 Pattern& Pattern::apply_flip(int f, bool CS) { 419 int newSizeX = max(Pattern::flipsX(f,0,0,sizeX,sizeY), 420 Pattern::flipsX(f,sizeX,sizeY,sizeX,sizeY)); 421 int newSizeY = max(Pattern::flipsY(f,0,0,sizeX,sizeY), 422 Pattern::flipsY(f,sizeX,sizeY,sizeX,sizeY)); 423 424 int newLeft = min(Pattern::flipsX(f,left,top,boardsize-1,boardsize-1), 425 Pattern::flipsX(f,right+sizeX-1,bottom+sizeY-1, 426 boardsize-1,boardsize-1)); 427 int newRight = max(Pattern::flipsX(f,left,top,boardsize-1,boardsize-1), 428 Pattern::flipsX(f,right+sizeX-1,bottom+sizeY-1, 429 boardsize-1,boardsize-1)) - (newSizeX-1); 430 int newTop = min(Pattern::flipsY(f,left,top,boardsize-1,boardsize-1), 431 Pattern::flipsY(f,right+sizeX-1,bottom+sizeY-1, 432 boardsize-1,boardsize-1)); 433 int newBottom = max(Pattern::flipsY(f,left,top,boardsize-1,boardsize-1), 434 Pattern::flipsY(f,right+sizeX-1,bottom+sizeY-1, 435 boardsize-1,boardsize-1)) - (newSizeY - 1); 436 437 // printf("%d, %d, %d, %d, %d, %d, %d\n", f, newSizeX, newSizeY, newLeft, newRight, newTop, newBottom); 438 char* newInitialPos = new char[sizeX*sizeY]; 439 int i=0; 440 for(i=0; i<sizeX; i++) { 441 for(int j=0; j<sizeY; j++) { 442 if (!CS) 443 newInitialPos[Pattern::flipsX(f,i,j,sizeX-1,sizeY-1) + \ 444 newSizeX*Pattern::flipsY(f,i,j,sizeX-1,sizeY-1)] = getInitial(i, j); 445 else 446 newInitialPos[Pattern::flipsX(f,i,j,sizeX-1,sizeY-1) + \ 447 newSizeX*Pattern::flipsY(f,i,j,sizeX-1,sizeY-1)] = 448 invertColor(getInitial(i, j)); 449 } 450 } 451 452 vector<MoveNC> newContList; 453 for(i=0; (unsigned int)i<contList.size(); i++) { 454 if (!CS) 455 newContList.push_back(MoveNC(Pattern::flipsX(f, contList[i].x, contList[i].y, 456 sizeX-1,sizeY-1), 457 Pattern::flipsY(f, contList[i].x, contList[i].y, 458 sizeX-1,sizeY-1), 459 contList[i].color)); 460 else 461 newContList.push_back(MoveNC(Pattern::flipsX(f, contList[i].x, contList[i].y, 462 sizeX-1,sizeY-1), 463 Pattern::flipsY(f, contList[i].x, contList[i].y, 464 sizeX-1,sizeY-1), 465 invertColor(contList[i].color))); 466 } 467 468 Pattern* pNew =new Pattern(newLeft, newRight, newTop, newBottom, boardsize, newSizeX, newSizeY, 469 newInitialPos, newContList); 470 471 pNew->flip = f; 472 if (CS) pNew->colorSwitch = 1; 473 delete [] newInitialPos; 474 return *pNew; 475 } 476 477 Pattern& Pattern::subpattern(int offsetX, int offsetY, int SIZEX, int SIZEY) { 478 int newLeft = left + offsetX; 479 int newRight = right + offsetX; 480 int newTop = top + offsetY; 481 int newBottom = bottom + offsetY; 482 483 char* newInitialPos = new char[SIZEX*SIZEY]; 484 int i=0; 485 for(i=0; i<SIZEX; i++) { 486 for(int j=0; j<SIZEY; j++) { 487 newInitialPos[i + SIZEX*j] = getInitial(i+offsetX, j+offsetY); 488 } 489 } 490 491 vector<MoveNC> newContList; 492 for(i=0; (unsigned int)i<contList.size(); i++) { 493 newContList.push_back(MoveNC(contList[i].x-offsetX, contList[i].y-offsetY, contList[i].color)); 494 } 495 496 Pattern* pNew =new Pattern(newLeft, newRight, newTop, newBottom, boardsize, SIZEX, SIZEY, 497 newInitialPos, newContList); 498 499 pNew->flip = flip; 500 pNew->colorSwitch = colorSwitch; 501 delete [] newInitialPos; 502 return *pNew; 503 } 504 415 505 string Pattern::printPattern() { 416 506 string result; … … 428 518 return result; 429 519 } 430 431 520 432 521 int Pattern::flipsX(int i, int x, int y, int XX, int YY) { … … 454 543 } 455 544 456 457 545 int Pattern::PatternInvFlip(int i) { 458 546 if (i == 5) return 6; … … 475 563 } 476 564 565 477 566 PatternList::PatternList(Pattern& p, int fColor, int nMove) throw(PatternError) { 478 pattern .copy(p);567 pattern = p; 479 568 fixedColor = fColor; 480 569 nextMove = nMove; … … 492 581 } 493 582 494 char PatternList::invertColor(char co) {495 if (co == 'X') return 'O';496 if (co == 'x') return 'o';497 498 if (co == 'O') return 'X';499 if (co == 'o') return 'x';500 501 return co;502 }503 504 583 void PatternList::patternList() { 505 584 … … 509 588 510 589 for(int f = 0; f < 8; f++) { 511 int newSizeX = max(Pattern::flipsX(f,0,0,pattern.sizeX,pattern.sizeY), 512 Pattern::flipsX(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY)); 513 int newSizeY = max(Pattern::flipsY(f,0,0,pattern.sizeX,pattern.sizeY), 514 Pattern::flipsY(f,pattern.sizeX,pattern.sizeY,pattern.sizeX,pattern.sizeY)); 515 516 int newLeft = min(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1), 517 Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1, 518 boardsize-1,boardsize-1)); 519 int newRight = max(Pattern::flipsX(f,pattern.left,pattern.top,boardsize-1,boardsize-1), 520 Pattern::flipsX(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1, 521 boardsize-1,boardsize-1)) - (newSizeX-1); 522 int newTop = min(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1), 523 Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1, 524 boardsize-1,boardsize-1)); 525 int newBottom = max(Pattern::flipsY(f,pattern.left,pattern.top,boardsize-1,boardsize-1), 526 Pattern::flipsY(f,pattern.right+pattern.sizeX-1,pattern.bottom+pattern.sizeY-1, 527 boardsize-1,boardsize-1)) - (newSizeY - 1); 528 529 // printf("%d, %d, %d, %d, %d, %d, %d\n", f, newSizeX, newSizeY, newLeft, newRight, newTop, newBottom); 530 char* newInitialPos = new char[pattern.sizeX*pattern.sizeY]; 531 int i=0; 532 for(i=0; i<pattern.sizeX; i++) { 533 for(int j=0; j<pattern.sizeY; j++) { 534 newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + \ 535 newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] = pattern.getInitial(i, j); 536 } 537 } 538 539 vector<MoveNC> newContList; 540 for(i=0; (unsigned int)i<pattern.contList.size(); i++) { 541 newContList.push_back(MoveNC(Pattern::flipsX(f, pattern.contList[i].x, pattern.contList[i].y, 542 pattern.sizeX-1,pattern.sizeY-1), 543 Pattern::flipsY(f, pattern.contList[i].x, pattern.contList[i].y, 544 pattern.sizeX-1,pattern.sizeY-1), 545 pattern.contList[i].color)); 546 } 547 548 Pattern pNew(newLeft, newRight, newTop, newBottom, pattern.boardsize, newSizeX, newSizeY, 549 newInitialPos, newContList); 550 551 pNew.flip = f; 552 // printf("new size %d %d\n", pNew.sizeX, pNew.sizeY); 553 554 delete [] newInitialPos; 590 Pattern pNew = pattern.apply_flip(f); 555 591 556 592 vector<Pattern>::iterator it; … … 570 606 if (pNew == pattern) sy.push_back(pair<int,int>(f,0)); 571 607 572 if (nextMove || !fixedColor) { 573 char* newInitialPos = new char[pattern.sizeX*pattern.sizeY]; 574 for(int i=0; i<pattern.sizeX; i++) { 575 for(int j=0; j<pattern.sizeY; j++) { 576 newInitialPos[Pattern::flipsX(f,i,j,pattern.sizeX-1,pattern.sizeY-1) + newSizeX*Pattern::flipsY(f,i,j,pattern.sizeX-1,pattern.sizeY-1)] = 577 invertColor(pattern.getInitial(i, j)); 578 } 579 } 580 vector<MoveNC> newContList; 581 { 582 for(unsigned int i=0; i<pattern.contList.size(); i++) { 583 newContList.push_back(MoveNC(Pattern::flipsX(f, pattern.contList[i].x, pattern.contList[i].y, 584 pattern.sizeX-1,pattern.sizeY-1), 585 Pattern::flipsY(f, pattern.contList[i].x, pattern.contList[i].y, 586 pattern.sizeX-1,pattern.sizeY-1), 587 invertColor(pattern.contList[i].color))); 588 } 589 } 590 591 592 // printf("new size %d %d", newSizeX, newSizeY); 593 Pattern pNew1(newLeft, newRight, newTop, newBottom, pattern.boardsize, newSizeX, newSizeY, 594 newInitialPos, newContList); 595 pNew1.flip = f; 596 pNew1.colorSwitch = 1; 597 598 delete [] newInitialPos; 599 600 if (!fixedColor) { 608 if (nextMove || !fixedColor) { // need to consider CS'ed patterns 609 Pattern pNew1 = pattern.apply_flip(f, 1); 610 611 if (!fixedColor) { 612 // need to add CS'ed pattern to patternList 613 // (if fixedColor==1 (but also nextMove!=0), we only need the CS'ed patterns to deal with 614 // continuations/the "symmetries" data 601 615 bool foundNewPattern = true; 602 616 int lCS_ctr = 0; … … 621 635 } 622 636 637 // add the new CS'ed patterns to data, and update flipTable 623 638 int lCS_ctr = 0; 624 639 for(vector<Pattern>::iterator it = lCS.begin(); it != lCS.end(); it++) { … … 639 654 } 640 655 656 // compute the "symmetries" 641 657 Symmetries symm(pattern.sizeX, pattern.sizeY); 642 658 for(int i=0; i<symm.sizeX; i++) … … 703 719 } 704 720 705 706 721 Pattern PatternList::get(int i) { 707 722 return data[i]; 708 723 } 709 724 710 711 725 int PatternList::size() { 712 726 return data.size(); 713 727 } 714 715 728 716 729 char* PatternList::updateContinuations(int index, int x, int y, char co, bool tenuki, char winner) { … … 762 775 } 763 776 764 765 777 char* PatternList::sortContinuations() { 766 778 char* labels = new char[pattern.sizeX*pattern.sizeY+1]; … … 805 817 return labels; 806 818 } 819 807 820 808 821 DBError::DBError() { … … 861 874 void Algorithm::finalize_process() {} 862 875 int Algorithm::readDB(sqlite3* DB) { return 0; } 876 863 877 int Algorithm::search(PatternList& patternList, GameList& gl, SearchOptions& options) { 864 878 return -1; 865 879 } 880 866 881 867 882 Algo_signature::Algo_signature(int bsize) : Algorithm(bsize) { … … 1272 1287 } 1273 1288 1274 1275 1289 void Algo_movelist::AW_process(int x, int y) { 1276 1290 movelist.push_back((char)x); 1277 1291 movelist.push_back((char)(y | WHITE)); 1278 1292 } 1279 1280 1293 1281 1294 void Algo_movelist::AE_process(int x, int y, char removed) { … … 2093 2106 } 2094 2107 2095 2096 2108 typedef vector<HashhitF* >* vpsip; 2097 2109 2098 2099 HashVarInfo::HashVarInfo(hashtype CHC, vector<pair<hashtype, ExtendedMoveNumber>* > * LFC, 2100 ExtendedMoveNumber* MOVENUMBER, int NUMSTONES) { 2110 HashVarInfo::HashVarInfo(hashtype CHC, vector<pair<hashtype, ExtendedMoveNumber>* > * LFC, ExtendedMoveNumber* MOVENUMBER, int NUMSTONES) { 2101 2111 chc = CHC; 2102 2112 numStones = NUMSTONES; … … 2279 2289 } 2280 2290 2281 2282 2291 hashtype Algo_hash_full::compute_hashkey(Pattern& pattern) { 2283 2292 if (pattern.sizeX != boardsize || pattern.sizeY != boardsize) … … 2310 2319 return 0; 2311 2320 } 2312 2313 2321 2314 2322 int Algo_hash_full::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { … … 2409 2417 // ----------------------------------------------------------------------------------- 2410 2418 2419 HashQuery::HashQuery(std::string SQL, Pattern* p0, int OFF0, int FLIP0, hashtype HASHCODE0, Pattern* p1, int OFF1, int FLIP1) { 2420 sql = SQL; 2421 if (p0) pl0 = new PatternList(*p0,1,0); 2422 else pl0 = 0; 2423 if (p1) pl1 = new PatternList(*p1,1,0); 2424 else pl1 = 0; 2425 offset0 = OFF0; 2426 offset1 = OFF1; 2427 flip0 = FLIP0; 2428 flip1 = FLIP1; 2429 hashCode0 = HASHCODE0; 2430 } 2431 2432 HashQuery::~HashQuery() { 2433 if (pl0) delete pl0; 2434 if (pl1) delete pl1; 2435 } 2436 2437 2438 CompleteHashKey::CompleteHashKey(hashtype HASHCODE, int OFFSETX, int OFFSETY, int INDEX) { 2439 hashCode = HASHCODE; 2440 offsetX = OFFSETX; 2441 offsetY = OFFSETY; 2442 index = INDEX; 2443 } 2444 2445 CompleteHashKey::CompleteHashKey() { 2446 hashCode = NOT_HASHABLE; 2447 offsetX = 0; 2448 offsetY = 0; 2449 index = -1; 2450 } 2451 2452 2411 2453 Algo_hash::Algo_hash(int bsize, const string& DBNAMEEXT, int MAXNUMSTONES) : Algorithm(bsize) { 2412 2454 dbnameext = DBNAMEEXT; … … 2535 2577 } 2536 2578 2537 2538 pair<hashtype,int> Algo_hash::compute_hashkey(PatternList& pl, int CS) { 2539 return make_pair(NOT_HASHABLE,0); 2579 CompleteHashKey Algo_hash::compute_hashkey(PatternList& pl, int CS) { 2580 return CompleteHashKey(); 2540 2581 } 2541 2582 … … 2555 2596 } 2556 2597 2598 HashQuery Algo_hash::searchQuery(PatternList& patternList) { 2599 // returns the sql query to be used in the search method, 2600 // and the offset that has to be added to the positions stored in the db 2601 // (this is necessary since the subpattern used for the hashing may not be 2602 // located at the top left corner of the pattern) 2603 return HashQuery("", 0, 0, 0, 0, 0, 0, 0); 2604 } 2605 2606 vector<int>* flip_list(int fl, int flip, int* pattern_ft, int* subpattern_ft) { 2607 vector<int>* result = new vector<int>; 2608 bool used[8]; 2609 { for(int i=0; i<8; i++) used[i] = false; 2610 } 2611 { for(int i=0; i<8; i++) { 2612 if (subpattern_ft[i] || used[i]) continue; 2613 for(int j=1; j<8; j++) 2614 if (pattern_ft[j] == 0) used[Pattern::compose_flips(i,j)] = true; 2615 result->push_back(Pattern::compose_flips(Pattern::PatternInvFlip(fl), Pattern::compose_flips(flip, i))); 2616 } 2617 } 2618 return result; 2619 } 2557 2620 2558 2621 int Algo_hash::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 2559 2622 // return value: -1 = failure; 0 = ok, but have to check w/ Algo_movelist 2560 2623 bool cs = patternList.data[patternList.size()-1].colorSwitch; 2561 2624 vector<HashhitCS* >* results = new vector<HashhitCS* >; 2562 2625 2563 pair<hashtype, int> hco = compute_hashkey(patternList, 0); 2564 hashtype hashCode = hco.first; 2565 // printf("HC %lld\n", hashCode); 2566 hashtype hashCode2 = hashCode; 2567 if (hashCode == NOT_HASHABLE) { 2626 HashQuery query = searchQuery(patternList); 2627 if (query.sql == "") { // NOT_HASHABLE 2568 2628 delete results; 2569 2629 return -1; // failure 2570 2630 } 2571 int fl = patternList.data[hco.second].flip;2572 int fl2 = fl;2573 char buf[100];2574 sprintf(buf, "select gameid,position,hash from algo_hash_%d_%s where hash = %lld",2575 boardsize, dbnameext.c_str(), hashCode);2576 string sql = buf;2577 2578 bool cs = patternList.data[patternList.size()-1].colorSwitch;2579 if (cs) {2580 pair<hashtype, int> hco = compute_hashkey(patternList, 1);2581 hashCode2 = hco.first;2582 // printf("HC2 %lld\n", hashCode2);2583 if (hashCode == NOT_HASHABLE) {2584 delete results;2585 return -1; // failure2586 }2587 fl2 = patternList.data[hco.second].flip;2588 2589 if (hashCode != hashCode2) {2590 sprintf(buf, " or hash = %lld", hashCode2);2591 sql += buf;2592 }2593 }2594 sql += " order by gameid";2595 2631 2596 2632 if (gl.start_sorted() == 0) { 2597 2633 // query database 2598 2599 // printf("%s\n", sql); 2600 pair<vector<HashhitCS* >*, hashtype> rN(results, hashCode); 2601 sqlite3_exec(db, sql.c_str(), insert_result, &rN, 0); 2602 // printf("results->size() %d\n", results->size()); 2634 pair<vector<HashhitCS* >*, hashtype> rN(results, query.hashCode0); 2635 sqlite3_exec(db, query.sql.c_str(), insert_result, &rN, 0); 2603 2636 2604 2637 // communicate results of query to database 2605 2638 // 2639 // FIXME explain how we get from a hit for the sql query to a candidates entry! 2606 2640 vector<HashhitCS* >::iterator resultIT = results->begin(); 2607 2641 while (resultIT != results->end()) { … … 2611 2645 vector<Candidate* >* candidates = new vector<Candidate* >; 2612 2646 while ((*resultIT)->gameid == index) { 2613 //int pos = (*resultIT)->position % (1<<16);2647 int pos = (*resultIT)->position % (1<<16); 2614 2648 int ori = (*resultIT)->position / (1<<16); 2615 2649 // printf("%d %d\n", pos, ori); 2616 if (cs && hashCode == hashCode2) { // this is a somewhat pathological case ... 2617 int ind = patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)]; 2618 candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 2619 ind = patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)]; 2620 candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 2650 2651 int* pattern_flipTable = patternList.flipTable; 2652 int* subpattern_flipTable; 2653 int fl; 2654 int offset; 2655 if ((*resultIT)->cs) { 2656 subpattern_flipTable = query.pl1->flipTable; 2657 fl = query.flip1; 2658 offset = query.offset1; 2621 2659 } else { 2622 if ((*resultIT)->cs) { 2623 // FIXME works only for corner patterns right now! 2624 int ind = patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)]; 2625 // printf("cand cs %d %d %d\n", patternList.flipTable[8+Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl2)], patternList.data[ind].left, patternList.data[ind].top); 2626 candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 2627 } else { 2628 int ind = patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)]; 2629 // printf("cand %d %d %d\n", patternList.flipTable[Pattern::compose_flips(Pattern::PatternInvFlip(ori),fl)], patternList.data[ind].left, patternList.data[ind].top); 2630 candidates->push_back(new Candidate(patternList.data[ind].left, patternList.data[ind].top, ind)); 2631 } 2660 subpattern_flipTable = query.pl0->flipTable; 2661 fl = query.flip0; 2662 offset = query.offset0; 2632 2663 } 2664 vector<int>* f_list = flip_list(fl, ori, pattern_flipTable, subpattern_flipTable); 2665 for(vector<int>::iterator flip = f_list->begin(); flip != f_list->end(); flip++) { 2666 // position = pos - flip(p.offset) 2667 int pos_left = 0; 2668 int pos_top = 0; 2669 2670 candidates->push_back(new Candidate(pos_left, pos_top, *flip)); 2671 } 2672 delete f_list; 2633 2673 resultIT++; 2634 2674 if (resultIT == results->end()) break; … … 2648 2688 sprintf(buf, "%d", size); 2649 2689 dbnameext += buf; 2690 } 2691 2692 void Algo_hash_corner::initialize_process(sqlite3* DB) throw(DBError) { 2693 Algo_hash::initialize_process(DB); 2650 2694 hi = new vector<HashInstance* >; 2651 2695 hi->push_back(new HashInstanceCO(0,0,size,size,boardsize)); 2652 hi->push_back(new HashInstanceCO(0,b size-size,size,size,boardsize));2653 hi->push_back(new HashInstanceCO(b size-size,0,size,size,boardsize));2654 hi->push_back(new HashInstanceCO(b size-size, bsize-size, size, size,boardsize));2655 } 2656 2657 pair<hashtype,int>Algo_hash_corner::compute_hashkey(PatternList& pl, int CS) {2658 if (pl.data[0].sizeX < size || pl.data[0].sizeY < size || pl.data[0].left != pl.data[0].right || pl.data[0].top != pl.data[0].bottom || (pl.data[0].left != 0 && pl.data[0].left != boardsize-size) || (pl.data[0].top != 0 && pl.data[0].top != boardsize-size)) return make_pair(NOT_HASHABLE,0);2696 hi->push_back(new HashInstanceCO(0,boardsize-size,size,size,boardsize)); 2697 hi->push_back(new HashInstanceCO(boardsize-size,0,size,size,boardsize)); 2698 hi->push_back(new HashInstanceCO(boardsize-size, boardsize-size, size, size,boardsize)); 2699 } 2700 2701 CompleteHashKey Algo_hash_corner::compute_hashkey(PatternList& pl, int CS) { 2702 if (pl.data[0].sizeX < size || pl.data[0].sizeY < size || pl.data[0].left != pl.data[0].right || pl.data[0].top != pl.data[0].bottom || (pl.data[0].left != 0 && pl.data[0].left != boardsize-size) || (pl.data[0].top != 0 && pl.data[0].top != boardsize-size)) return CompleteHashKey(); 2659 2703 hashtype hk = NOT_HASHABLE; 2660 2704 int f = 0; 2705 int oX = 0; 2706 int oY = 0; 2661 2707 vector<hashtype> hCodes; 2662 2708 for(int pCtr=0; pCtr<pl.size(); pCtr++) { … … 2673 2719 for(int j=0; j<size; j++) { 2674 2720 char p = pattern->finalPos[i+offsetX + pattern->sizeX*(j+offsetY)]; 2675 if (p == 'x' || p == 'o' || p == '*') return make_pair(NOT_HASHABLE,0);2721 if (p == 'x' || p == 'o' || p == '*') return CompleteHashKey(); 2676 2722 else if (p == 'X') { 2677 2723 hashkey += hashCodes[i+offsetX+pattern->left + boardsize*(j+offsetY+pattern->top)]; … … 2683 2729 } 2684 2730 } 2685 if (ns > maxNumStones) return make_pair(NOT_HASHABLE,0);2731 if (ns > maxNumStones) return CompleteHashKey(); // NOT_HASHABLE 2686 2732 2687 2733 // make sure all hash keys are unique 2688 2734 for(vector<hashtype>::iterator it = hCodes.begin(); it != hCodes.end(); it++) 2689 if (*it == hashkey) return make_pair(NOT_HASHABLE, 0);2735 if (*it == hashkey) return CompleteHashKey(); // NOT_HASHABLE 2690 2736 hCodes.push_back(hashkey); 2691 2737 … … 2693 2739 hk = hashkey; 2694 2740 f = pCtr; 2741 oX = offsetX; 2742 oY = offsetY; 2695 2743 } 2696 2744 } 2697 2745 } 2698 return make_pair(hk, f); 2699 } 2746 return CompleteHashKey(hk, oX, oY, f); 2747 } 2748 2749 HashQuery Algo_hash_corner::searchQuery(PatternList& patternList) { 2750 CompleteHashKey chk = compute_hashkey(patternList, 0); 2751 if (chk.hashCode == NOT_HASHABLE) return HashQuery("",0,0,0,0,0,0,0); 2752 int fl = patternList.data[chk.index].flip; 2753 2754 char buf[100]; 2755 sprintf(buf, "select gameid,position,hash from algo_hash_%d_%s where hash = %lld", 2756 boardsize, dbnameext.c_str(), chk.hashCode); 2757 string sql = buf; 2758 Pattern* p0; // FIXME 2759 int off0 = 0; 2760 2761 hashtype hashCode2 = chk.hashCode; 2762 int fl2 = fl; 2763 Pattern* p1 = 0; 2764 int off1 = 0; 2765 if (patternList.data[patternList.size()-1].colorSwitch) { 2766 CompleteHashKey hco = compute_hashkey(patternList, 1); 2767 hashCode2 = hco.hashCode; 2768 // printf("HC2 %lld\n", hashCode2); 2769 if (chk.hashCode == NOT_HASHABLE) return HashQuery("",0,0,0,0,0,0,0); 2770 fl2 = patternList.data[hco.index].flip; 2771 2772 if (chk.hashCode != hashCode2) { 2773 sprintf(buf, " or hash = %lld", hashCode2); 2774 sql += buf; 2775 } 2776 } 2777 sql += " order by gameid"; 2778 return HashQuery(sql, p0, off0, fl, chk.hashCode, p1, off1, fl2); // FIXME: need to create subpatterns!, compute offsets 2779 } 2780 2700 2781 2701 2782 // Algo_hash_side::Algo_hash_side(int bsize, int SIZEX, int SIZEY) : Algo_hash(bsize, "SIDE") { … … 2719 2800 2720 2801 Algo_hash_center::Algo_hash_center(int bsize) : Algo_hash(bsize, "CENTER", 16) { 2721 hi = new vector<HashInstance* >; 2722 for(int i=1; i<bsize-4; i++) 2723 for(int j=1; j<bsize-4; j++) 2724 hi->push_back(new HashInstanceCTR(i, j, 4, 4, boardsize)); 2802 // read "frequency" table from kombilo.db 2803 sqlite3* kombilodb = 0; 2804 int rc = sqlite3_open("kombilo.db", &kombilodb); // FIXME path to kombilo.db?! 2805 2806 rc = sqlite3_exec(kombilodb, "begin transaction;", 0, 0, 0); 2807 if (rc) throw DBError(); 2808 sqlite3_stmt *ppStmt=0; 2809 rc = sqlite3_prepare(kombilodb, "select hash, freq from frequency;", -1, &ppStmt, 0); 2810 // if (rc != SQLITE_OK || ppStmt==0) return rc; // FIXME: catch certain errors, (and/or throw DBError?) 2811 while (sqlite3_step(ppStmt) == SQLITE_ROW) { 2812 frequency.insert(make_pair(sqlite3_column_int64(ppStmt, 0), sqlite3_column_int(ppStmt, 1))); 2813 } 2814 if (rc != SQLITE_OK) printf("SQLITE errorA %d\n", rc); // FIXME 2815 rc = sqlite3_finalize(ppStmt); 2816 if (rc != SQLITE_OK) printf("SQLITE errorB %d\n", rc); 2817 rc = sqlite3_exec(kombilodb, "commit;", 0, 0, 0); 2818 if (rc != SQLITE_OK) printf("SQLITE errorC %d\n", rc); 2819 rc = sqlite3_close(kombilodb); 2820 if (rc != SQLITE_OK) printf("SQLITE errorD %d\n", rc); 2725 2821 } 2726 2822 2727 2823 void Algo_hash_center::endOfNode_process() { 2728 2824 for(vector<HashInstance* >::iterator it = hi->begin(); it != hi->end(); it++) { 2729 if ((*it)-> numStones <= maxNumStones && (*it)->changed) {2825 if ((*it)->changed) { 2730 2826 (*it)->changed = false; 2731 2827 pair<hashtype,int> phi = (*it)->cHC(); 2732 if (phi.first in table of relevant hash codes) 2828 map<hashtype, int>::iterator freq_it = frequency.find(phi.first); 2829 if (freq_it != frequency.end() && freq_it->second > 100 && freq_it->second < 1000) 2733 2830 if (insert_hash(phi.first, phi.second) != 0) throw DBError(); 2734 2831 } … … 2736 2833 } 2737 2834 2738 2739 pair<hashtype,int> Algo_hash_center::compute_hashkey(PatternList& pl, int CS) { 2740 return make_pair(NOT_HASHABLE,0); 2741 } 2742 2835 void Algo_hash_center::initialize_process(sqlite3* DB) throw(DBError) { 2836 db = DB; 2837 char buf[200]; 2838 sprintf(buf, "create table if not exists algo_hash_%d_%s ( hash integer, gameid integer, position integer );", boardsize, dbnameext.c_str()); 2839 int rc = sqlite3_exec(db, buf, 0, 0, 0); 2840 if (rc != SQLITE_OK) throw DBError(); 2841 // create index in finalize_process in this case 2842 sprintf(buf, "drop index if exists hash_idx_%d_%s on algo_hash_%d_%s(hash);", boardsize, dbnameext.c_str(), boardsize, dbnameext.c_str()); 2843 rc = sqlite3_exec(db, buf, 0, 0, 0); 2844 if (rc != SQLITE_OK) throw DBError(); 2845 2846 hi = new vector<HashInstance* >; 2847 for(int i=0; i<boardsize-3; i++) // FIXME: boundaries 2848 for(int j=0; j<boardsize-3; j++) 2849 hi->push_back(new HashInstanceCTR(i, j, 4, 4, boardsize)); 2850 } 2851 2852 void Algo_hash_center::finalize_process() { 2853 char buf[200]; 2854 sprintf(buf, "create index if not exists hash_idx_%d_%s on algo_hash_%d_%s(hash);", boardsize, dbnameext.c_str(), boardsize, dbnameext.c_str()); 2855 int rc = sqlite3_exec(db, buf, 0, 0, 0); 2856 if (rc != SQLITE_OK) throw DBError(); 2857 } 2858 2859 hashtype center_hashkey(char* p, int sizeX, int start) { 2860 // computes the hash key of the 4x4 pattern in p 2861 hashtype currentHashCode[8]; 2862 for(int f=0; f<8; f++) { 2863 for(int x=0; x<4; x++) { 2864 for(int y=0; y<4; y++) { 2865 char x1 = Pattern::flipsX(f, x, y, 3, 3); 2866 char y1 = Pattern::flipsY(f, x, y, 3, 3); 2867 char c = p[start + x1*sizeX + y1]; 2868 // stone at position (x1, y1) at bits 4*x1+yy1 4*x1+y1+1 2869 int p = 2*(4*x1+y1); 2870 if (c=='X') 2871 currentHashCode[f] |= 1 << p; // set to 01 = black 2872 else if (c == 'W') 2873 currentHashCode[f] |= 1 << p+1; // set to 10 = white 2874 else if (c != '.') return NOT_HASHABLE; 2875 } 2876 } 2877 } 2878 hashtype minCHC = currentHashCode[0]; 2879 for(int f=1; f<8; f++) { 2880 if (currentHashCode[f] < minCHC) { 2881 minCHC = currentHashCode[f]; 2882 } 2883 } 2884 return minCHC; 2885 } 2886 2887 CompleteHashKey Algo_hash_center::compute_hashkey(PatternList& pl, int CS) { 2888 if (pl.pattern.sizeX < 4 || pl.pattern.sizeY < 4 || 2889 (pl.pattern.sizeX < 5 && (pl.pattern.left == 0 || pl.pattern.right == boardsize-1)) || 2890 (pl.pattern.sizeY < 5 && (pl.pattern.top == 0 || pl.pattern.bottom == boardsize-1))) 2891 return CompleteHashKey(); // NOT_HASHABLE 2892 2893 // go through all center 4x4 sub-patterns, and compute the corresp. hash key 2894 2895 int X1 = 0; 2896 int Y1 = 0; 2897 int X2 = pl.pattern.sizeX - 4; 2898 int Y2 = pl.pattern.sizeY - 4; 2899 2900 // if (pl.pattern.left == 0) X1++; 2901 // if (pl.pattern.top == 0) Y1++; 2902 // if (pl.pattern.right == boardsize - pl.pattern.sizeX) X2--; 2903 // if (pl.pattern.bottom == boardsize - pl.pattern.sizeY) Y2--; 2904 2905 // 2906 return CompleteHashKey(); // NOT_HASHABLE 2907 } 2908 2909 HashQuery Algo_hash_center::searchQuery(PatternList& patternList) { 2910 return HashQuery("",0,0,0,0,0,0,0); 2911 } 2743 2912 2744 2913 … … 2820 2989 branchpoints->pop(); 2821 2990 } 2822 2823 2991 2824 2992 HashInstanceCO::HashInstanceCO(char X, char Y, char SIZEX, char SIZEY, int BOARDSIZE) : HashInstance(X, Y, SIZEX, SIZEY, BOARDSIZE) { … … 3364 3532 // } 3365 3533 3366 3367 3368 3369 3534 // ---------------------------------------------------------------------------------------------- 3370 3535 … … 4406 4571 int pos = 0; 4407 4572 while (root) { 4573 printf("current: %d\n", current); 4408 4574 current++; 4409 // if (!(current%1000)) { 4410 // char* sql = "end transaction;"; 4411 // int rc = sqlite3_exec(db, sql, 0, 0, 0); 4412 // if (rc) { 4413 // sqlite3_close(db); 4414 // db = 0; 4415 // throw DBError(); 4416 // } 4417 // sql = "begin transaction;"; 4418 // rc = sqlite3_exec(db, sql, 0, 0, 0); 4419 // if (rc) { 4420 // sqlite3_close(db); 4421 // db = 0; 4422 // throw DBError(); 4423 // } 4424 // } 4575 if (algo_db2 && !(current%5000)) { 4576 int rc = sqlite3_exec(algo_db2, "commit", 0, 0, 0); 4577 if (rc) { 4578 sqlite3_close(db); 4579 db = 0; 4580 throw DBError(); 4581 } 4582 rc = sqlite3_exec(algo_db2, "begin transaction", 0, 0, 0); 4583 if (rc) { 4584 sqlite3_close(db); 4585 db = 0; 4586 throw DBError(); 4587 } 4588 } 4425 4589 vector<string>* rootNodeProperties = parseRootNode(root, SGFtags); 4426 4590 // for(vector<string>::iterator rnp = rootNodeProperties->begin(); rnp != rootNodeProperties->end(); rnp++) 06/libkombilo-branches/hash_center/search.h
r233 r238 82 82 const int FULLBOARD_PATTERN = 9; 83 83 84 class PatternList; 85 84 86 class Pattern { 85 87 public: … … 99 101 char* contLabels; 100 102 std::vector<MoveNC> contList; 103 101 104 102 105 // Pattern constructors … … 117 120 Pattern& copy(const Pattern& p); 118 121 122 Pattern& apply_flip(int f, bool CS = true); 123 Pattern& subpattern(int offsetX, int offsetY, int sizeX, int sizeY); 119 124 char getInitial(int i, int j); 120 125 char getFinal(int i, int j); … … 128 133 static int PatternInvFlip(int i); 129 134 static int compose_flips(int i, int j); // returns index of flip "first j, then i" 135 // static int compose_flips_CS(int i, int j); // similarly, but taking CS into account (i.e. 0<=i,j<16) 130 136 }; 131 137 … … 151 157 std::vector<Symmetries> symmetries; 152 158 Continuation* continuations; 159 // flipTable encodes the action of the group of symmetries of the square times Z/2 (for color switch) 160 // on pattern: flipTable[i] is the index in data of the pattern resulting from applying flip i and no 161 // CS (0<=i<8), or flip i-8 and CS (8<=i<16) to pattern. 153 162 int* flipTable; 163 // special is -1, or equal to the inverse of the flip which maps pattern to its CS'ed pattern 154 164 int special; 155 165 … … 157 167 ~PatternList(); 158 168 159 char invertColor(char co);169 // static char invertColor(char co); 160 170 void patternList(); 161 171 Pattern get(int i); … … 342 352 }; 343 353 344 class HashhitCS { // has ihing hit for corner/sidepattern search354 class HashhitCS { // hashing hit for corner/side/center pattern search 345 355 public: 346 356 int gameid; … … 443 453 }; 444 454 455 class CompleteHashKey { 456 // returned by compute_hashkey 457 // contains the information about which subpattern was used to compute the actual hashCode 458 public: 459 hashtype hashCode; 460 int offsetX; 461 int offsetY; 462 int index; // index in corresp. patternList 463 464 CompleteHashKey(); // = NOT_HASHABLE 465 CompleteHashKey(hashtype HASHCODE, int OFFSETX, int OFFSETY, int INDEX); 466 }; 467 468 class HashQuery { 469 public: 470 std::string sql; 471 PatternList* pl0; 472 PatternList* pl1; 473 int flip0; 474 int flip1; 475 int offset0; 476 int offset1; 477 hashtype hashCode0; 478 479 HashQuery(std::string SQL, Pattern* p0, int OFF0, int FLIP0, hashtype HASHCODE0, Pattern* p1, int OFF1, int FLIP1); 480 ~HashQuery(); 481 }; 445 482 446 483 class Algo_hash : public Algorithm { … … 463 500 virtual void endgame_process(); 464 501 virtual void finalize_process(); 502 virtual HashQuery searchQuery(PatternList& patternList); 465 503 virtual int search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db); 466 504 467 505 virtual int insert_hash(hashtype hashCod, int pos); 468 virtual std::pair<hashtype,int>compute_hashkey(PatternList& pl, int CS);506 virtual CompleteHashKey compute_hashkey(PatternList& pl, int CS); 469 507 std::vector<HashInstance* >* hi; 470 508 std::string dbnameext; … … 477 515 public: 478 516 Algo_hash_corner(int bsize, int SIZE=7, int MAXNUMSTONES = 20); 479 std::pair<hashtype,int> compute_hashkey(PatternList& pl, int CS); 517 CompleteHashKey compute_hashkey(PatternList& pl, int CS); 518 void initialize_process(sqlite3* DB) throw(DBError); 519 HashQuery searchQuery(PatternList& patternList); 480 520 int size; 481 521 }; … … 492 532 Algo_hash_center(int bsize); 493 533 void initialize_process(sqlite3* DB) throw(DBError); 534 void finalize_process(); 494 535 void endOfNode_process(); 495 void finalize_process();496 std::pair<hashtype,int> compute_hashkey(PatternList& pl, int CS);536 CompleteHashKey compute_hashkey(PatternList& pl, int CS); 537 HashQuery searchQuery(PatternList& patternList); 497 538 498 539 std::map<hashtype, int> data; 540 private: 541 std::map<hashtype, int> frequency; 499 542 }; 500 543
