// Search config in the hash table, if it is not there, this config will be // inserted. If inserted, *pCacheConfig will point to the location. // return value // 0 -- not found or can not be pruned // 1 -- find a config that can be pruned in the cache int TryFind(CConfig **arr, CConfig *pConfig, CConfig **pCacheConfig) { *pCacheConfig = NULL; //return 0; int index = pConfig->CalHashValue(); CConfig *p = arr[index]; if (!p) // the config is not found and insert this pConfig to it { #ifdef USE_OWN_CACHE if (usedconfiglength>=MAXUSEDCONFIGSIZE) return 0; CConfig* pNewConfig = newCacheConfig(pConfig->len); if (!pNewConfig) return 0; // cache has been used up, just return; #else if (usedconfiglength>=MAXUSEDCONFIGSIZE) return 0; CConfig* pNewConfig = new CConfig(pConfig->len); assert(pNewConfig); #endif usedconfiglength++; pNewConfig->Copy(pConfig); arr[index] = pNewConfig; *pCacheConfig = pNewConfig; return 0; } if (p->ConfigCmp(pConfig)) return 0; // now the configs are the same if (p->depth <= pConfig->depth) { // if a config hits the hash table with length no less than that in the // table, it cannot be on the path of any optimal solutions not found // yet. Remember if an optimal solution is found, all configs along // the solution path stored in the hash table are released in // Solution_Found() in solver.cpp return 1; } else { p->depth = pConfig->depth; *pCacheConfig = p; return 0; } }
//FILE *errfile=fopen("errfile.txt", "w"); // routine to deal with the situation when one solution is found including // record the solution, check the solution, update solving results and search // parameters. // return value: // >0 should return the length immediately (When only need find one solution // =0 continue to find other solutions int CSolver::Solution_Found(CPCPInstance *pPCP, CConfig *pConfig) { int k; // for test, may not be solution, so need not record length and count if (globalStatus == FIND_MASK || globalStatus == EXCLUSION_METHOD) return pConfig->depth; // just to find solution if (!FindShortestSolution_Flag) { solution_length = pConfig->depth; solution_count = 1; return pConfig->depth; } // find all solutions if ( globalStatus == COMPARE_DIRECTION || globalStatus == ITERATIVE_SEARCH || globalStatus == DETERMINANT_SEARCH) { #ifdef SOLVER_OUTPUT // print the solution //if (pConfig->depth <= solution_length) // for special purposes /** BUG FIX 061031 1. Originally, the first solution (may be optimal) is always omitted. to fix that, now suboptimal solutions can be output as well. 2. During bidirectioanl probing process, no solution should be output. **/ if (globalStatus != COMPARE_DIRECTION) PrintSolution(arrSelection, pConfig->depth); #endif // find all solutions not only including the shortest ones if (Iterative_Flag == 0 && FindAllSolutions_Flag == 1) solution_count++; // find only all shortest solutions else if (pConfig->depth < solution_length || solution_length == 0) { solution_length = pConfig->depth; solution_count = 1; iterative_depth_threshold = solution_length; } // find one more solution for the length else if (pConfig->depth == solution_length) solution_count++; // find all configs in the solution path and free them if they are // in the hashtable CConfig tempConfig(pConfig->depth * pPCP->offset); for (k=1;k<=pConfig->depth;k++) { // need improvement for exclusion method assert( (arrSelection[k]>=1) && (arrSelection[k]<=pPCP->size) ); // add the pair tempConfig.MatchPair(&pPCP->arrPair[arrSelection[k]-1], arrSelection); tempConfig.ConfigPrintToConsole(); //tempConfig.ConfigPrint(errfile); // make up the visited node count node_num--; // find in the cache int hashvalue = tempConfig.CalHashValue(); CConfig *p = hashTable[hashvalue]; if (!p) continue; if (p->ConfigCmp(&tempConfig)) continue; // update the depth threshold p->depth = iterative_depth_threshold; } assert(tempConfig.len==0); // for debugging } return 0; }